summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Rossi <nathan.rossi@xilinx.com>2013-07-12 13:39:36 +1000
committerNathan Rossi <nathan.rossi@xilinx.com>2013-07-12 13:39:36 +1000
commit46f4c79d6d55b556a90bb0fd89c2c09acf2aebff (patch)
tree8b82c52b597b8aa0d34e3238199d3146be433c46
parentfb387c1fc62323cb524f5ed00d41e54c5c657153 (diff)
parent867fe421ef8dc0cbe4c1734acb982185a596901b (diff)
downloadmeta-xilinx-46f4c79d6d55b556a90bb0fd89c2c09acf2aebff.tar.gz
Merge MicroBlaze Toolchain Enablement.
-rw-r--r--conf/machine/qemumicroblaze.conf2
-rw-r--r--recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend1
-rw-r--r--recipes-devtools/binutils/binutils-cross_2.23.2.bbappend1
-rw-r--r--recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend1
-rw-r--r--recipes-devtools/binutils/binutils-microblaze-2.23.2.inc18
-rw-r--r--recipes-devtools/binutils/binutils_2.23.2.bbappend1
-rw-r--r--recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch243
-rw-r--r--recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch30
-rw-r--r--recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch632
-rw-r--r--recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch63
-rw-r--r--recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch89
-rw-r--r--recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch143
-rw-r--r--recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch76
-rw-r--r--recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch207
-rw-r--r--recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch149
-rw-r--r--recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch83
-rw-r--r--recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch89
-rw-r--r--recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch1371
-rw-r--r--recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch310
-rw-r--r--recipes-devtools/gcc/files/0001-Patch-microblaze-Enable-DWARF-exception-handling-sup.patch158
-rw-r--r--recipes-devtools/gcc/files/0002-Patch-microblaze-Add-4-byte-implementation-for-atomi.patch157
-rw-r--r--recipes-devtools/gcc/files/0003-Patch-microblaze-Extend-jump-insn-to-accept-bri-to-S.patch35
-rw-r--r--recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch116
-rw-r--r--recipes-devtools/gcc/files/0005-Patch-microblaze-Add-fstack-usage-support.patch30
-rw-r--r--recipes-devtools/gcc/files/0006-Patch-microblaze-Remove-SECONDARY_MEMORY_NEEDED.patch35
-rw-r--r--recipes-devtools/gcc/files/0007-Patch-microblaze-Add-SIZE_TYPE-and-PTRDIFF_TYPE-to-m.patch39
-rw-r--r--recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch224
-rw-r--r--recipes-devtools/gcc/files/Patch-microblaze-Fix-bswaphi2-implementation.patch44
-rw-r--r--recipes-devtools/gcc/files/Patch-microblaze-cstoresf4-add-mode-and-ordered_comp.patch44
-rw-r--r--recipes-devtools/gcc/gcc-cross-canadian_4.8.bbappend1
-rw-r--r--recipes-devtools/gcc/gcc-cross-initial_4.8.bbappend1
-rw-r--r--recipes-devtools/gcc/gcc-cross_4.8.bbappend1
-rw-r--r--recipes-devtools/gcc/gcc-crosssdk-initial_4.8.bbappend1
-rw-r--r--recipes-devtools/gcc/gcc-crosssdk_4.8.bbappend1
-rw-r--r--recipes-devtools/gcc/gcc-microblaze-4.8.inc15
-rw-r--r--recipes-devtools/gcc/gcc-runtime_4.8.bbappend1
-rw-r--r--recipes-devtools/gcc/gcc_4.8.bbappend1
-rw-r--r--recipes-devtools/gcc/libgcc_4.8.bbappend1
-rw-r--r--site/microblaze-common2
39 files changed, 4414 insertions, 2 deletions
diff --git a/conf/machine/qemumicroblaze.conf b/conf/machine/qemumicroblaze.conf
index e84dd9ae..1d19b80b 100644
--- a/conf/machine/qemumicroblaze.conf
+++ b/conf/machine/qemumicroblaze.conf
@@ -5,6 +5,6 @@
5MACHINE_FEATURES := "" 5MACHINE_FEATURES := ""
6 6
7require conf/machine/include/tune-microblaze.inc 7require conf/machine/include/tune-microblaze.inc
8TUNE_FEATURES_tune-microblaze += "v8.30 little-endian barrel-shift pattern-compare divide-hard multiply-high fpu-hard" 8TUNE_FEATURES_tune-microblaze += "v8.50 little-endian barrel-shift reorder pattern-compare divide-hard multiply-high fpu-hard"
9 9
10SERIAL_CONSOLE = "115200 ttyS0" 10SERIAL_CONSOLE = "115200 ttyS0"
diff --git a/recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend b/recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend
new file mode 100644
index 00000000..e42e7a60
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-cross-canadian_2.23.2.bbappend
@@ -0,0 +1 @@
require binutils-microblaze-${PV}.inc
diff --git a/recipes-devtools/binutils/binutils-cross_2.23.2.bbappend b/recipes-devtools/binutils/binutils-cross_2.23.2.bbappend
new file mode 100644
index 00000000..e42e7a60
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-cross_2.23.2.bbappend
@@ -0,0 +1 @@
require binutils-microblaze-${PV}.inc
diff --git a/recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend b/recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend
new file mode 100644
index 00000000..e42e7a60
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-crosssdk_2.23.2.bbappend
@@ -0,0 +1 @@
require binutils-microblaze-${PV}.inc
diff --git a/recipes-devtools/binutils/binutils-microblaze-2.23.2.inc b/recipes-devtools/binutils/binutils-microblaze-2.23.2.inc
new file mode 100644
index 00000000..71112efb
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-microblaze-2.23.2.inc
@@ -0,0 +1,18 @@
1
2# Add MicroBlaze Patches
3FILESEXTRAPATHS_append := "${THISDIR}/files:"
4SRC_URI_append += " \
5 file://0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch \
6 file://0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch \
7 file://0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch \
8 file://0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch \
9 file://0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch \
10 file://0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch \
11 file://0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch \
12 file://0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch \
13 file://0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch \
14 file://0010-7de425548753461fd2768017d3be677ba2b2a583.patch \
15 file://0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch \
16 file://0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch \
17 file://0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch \
18 "
diff --git a/recipes-devtools/binutils/binutils_2.23.2.bbappend b/recipes-devtools/binutils/binutils_2.23.2.bbappend
new file mode 100644
index 00000000..e42e7a60
--- /dev/null
+++ b/recipes-devtools/binutils/binutils_2.23.2.bbappend
@@ -0,0 +1 @@
require binutils-microblaze-${PV}.inc
diff --git a/recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch b/recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch
new file mode 100644
index 00000000..4f0993eb
--- /dev/null
+++ b/recipes-devtools/binutils/files/0001-9f0cfcdd4c342cc2a97bb4591c5542507f073435.patch
@@ -0,0 +1,243 @@
1From 9f0cfcdd4c342cc2a97bb4591c5542507f073435 Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Wed, 31 Oct 2012 15:27:35 +0000
4Subject: 2012-10-31 David Holsgrove <david.holsgrove@xilinx.com>
5
6 * config/tc-microblaze.c: Check for weak symbols before
7 emitting relocation.
8
92012-10-31 David Holsgrove <david.holsgrove@xilinx.com>
10
11 * gas/microblaze: New.
12 * gas/microblaze/reloc_sym.exp: Add test case.
13 * gas/microblaze/reloc_strongsym.s: Likewise.
14 * gas/microblaze/reloc_weaksym.s: Likewise.
15 * gas/microblaze/reloc_sym.d: Likewise.
16
17Upstream-Status: Backport
18
19diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
20index 3ab854f..86ac90b 100644
21--- a/gas/config/tc-microblaze.c
22+++ b/gas/config/tc-microblaze.c
23@@ -2065,7 +2065,8 @@ md_estimate_size_before_relax (fragS * fragP,
24 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
25 abort ();
26 }
27- else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type))
28+ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
29+ !S_IS_WEAK (fragP->fr_symbol))
30 {
31 fragP->fr_subtype = DEFINED_PC_OFFSET;
32 /* Don't know now whether we need an imm instruction. */
33diff --git a/gas/testsuite/gas/microblaze/reloc_strongsym.s b/gas/testsuite/gas/microblaze/reloc_strongsym.s
34new file mode 100644
35index 0000000..8f34028
36--- /dev/null
37+++ b/gas/testsuite/gas/microblaze/reloc_strongsym.s
38@@ -0,0 +1,20 @@
39+ .section ".testsection"
40+ .align 2
41+ .globl test_start
42+ .ent test_start
43+ .type test_start, @function
44+test_start:
45+ .frame r19,8,r15 # vars= 0, regs= 1, args= 0
46+ .mask 0x00080000
47+ addik r1,r1,-8
48+ swi r19,r1,4
49+ addk r19,r1,r0
50+ addk r1,r19,r0
51+ lwi r19,r1,4
52+ addik r1,r1,8
53+ rtsd r15,8
54+ nop # Unfilled delay slot
55+
56+ .end test_start
57+$Lfe1:
58+ .size test_start,$Lfe1-test_start
59diff --git a/gas/testsuite/gas/microblaze/reloc_sym.d b/gas/testsuite/gas/microblaze/reloc_sym.d
60new file mode 100644
61index 0000000..212d0bb
62--- /dev/null
63+++ b/gas/testsuite/gas/microblaze/reloc_sym.d
64@@ -0,0 +1,45 @@
65+
66+reloc_sym.x: file format elf32-microblaze
67+
68+
69+Disassembly of section .text:
70+
71+10000054 <__def_start>:
72+10000054: 3021fff8 addik r1, r1, -8
73+10000058: fa610004 swi r19, r1, 4
74+1000005c: 12610000 addk r19, r1, r0
75+10000060: 10330000 addk r1, r19, r0
76+10000064: ea610004 lwi r19, r1, 4
77+10000068: 30210008 addik r1, r1, 8
78+1000006c: b60f0008 rtsd r15, 8
79+10000070: 80000000 or r0, r0, r0
80+
81+10000074 <main>:
82+10000074: 3021ffe0 addik r1, r1, -32
83+10000078: f9e10000 swi r15, r1, 0
84+1000007c: fa61001c swi r19, r1, 28
85+10000080: 12610000 addk r19, r1, r0
86+10000084: b000efff imm -4097
87+10000088: b9f4ff7c brlid r15, -132 // 4 <test_start>
88+1000008c: 80000000 or r0, r0, r0
89+10000090: b9f4ffc4 brlid r15, -60 // 10000054 <__def_start>
90+10000094: 80000000 or r0, r0, r0
91+10000098: 10600000 addk r3, r0, r0
92+1000009c: e9e10000 lwi r15, r1, 0
93+100000a0: 10330000 addk r1, r19, r0
94+100000a4: ea61001c lwi r19, r1, 28
95+100000a8: 30210020 addik r1, r1, 32
96+100000ac: b60f0008 rtsd r15, 8
97+100000b0: 80000000 or r0, r0, r0
98+
99+Disassembly of section .testsection:
100+
101+00000004 <test_start>:
102+ 4: 3021fff8 addik r1, r1, -8
103+ 8: fa610004 swi r19, r1, 4
104+ c: 12610000 addk r19, r1, r0
105+ 10: 10330000 addk r1, r19, r0
106+ 14: ea610004 lwi r19, r1, 4
107+ 18: 30210008 addik r1, r1, 8
108+ 1c: b60f0008 rtsd r15, 8
109+ 20: 80000000 or r0, r0, r0
110diff --git a/gas/testsuite/gas/microblaze/reloc_sym.exp b/gas/testsuite/gas/microblaze/reloc_sym.exp
111new file mode 100644
112index 0000000..c7f7322
113--- /dev/null
114+++ b/gas/testsuite/gas/microblaze/reloc_sym.exp
115@@ -0,0 +1,27 @@
116+# Relocation test.
117+
118+proc ld_test { objects ldflags dest test } {
119+ set ld_output [target_link $objects $dest $ldflags]
120+ if [string match "" $ld_output] then { pass $test } else { fail $test }
121+}
122+
123+proc objdump_test { exec flags dest test } {
124+ set objcopy [find_binutils_prog objdump]
125+ verbose -log "$objcopy $flags $exec > $dest"
126+ catch "exec $objcopy $flags $exec > $dest" objdump_output
127+ if [string match "" $objdump_output] then { pass $test } else { fail $test }
128+}
129+
130+proc regexp_test { file1 file2 test } {
131+ if [regexp_diff $file1 $file2] then { fail $test } else { pass $test }
132+}
133+
134+
135+global srcdir subdir
136+if [istarget microblaze*-*-*] {
137+ gas_test "reloc_strongsym.s" {-o reloc_strongsym.o} {} {assembling reloc_strongsym}
138+ gas_test "reloc_weaksym.s" {-o reloc_weaksym.o} {} {assembling reloc_weaksym}
139+ ld_test {reloc_strongsym.o reloc_weaksym.o} {-e 0 -section-start .text=0x10000054 -section-start .testsection=0x4} {reloc_sym.x} {linking reloc_sym.x}
140+ objdump_test {reloc_sym.x} {-d --section=.text --section=.testsection} {reloc_sym.dump} {disassembling reloc_sym.x}
141+ regexp_test {reloc_sym.dump} "$srcdir/$subdir/reloc_sym.d" {matching disassembly}
142+}
143diff --git a/gas/testsuite/gas/microblaze/reloc_weaksym.s b/gas/testsuite/gas/microblaze/reloc_weaksym.s
144new file mode 100644
145index 0000000..7dd9b98
146--- /dev/null
147+++ b/gas/testsuite/gas/microblaze/reloc_weaksym.s
148@@ -0,0 +1,52 @@
149+ .text
150+ .align 2
151+ .globl __def_start
152+ .ent __def_start
153+ .type __def_start, @function
154+__def_start:
155+ .frame r19,8,r15 # vars= 0, regs= 1, args= 0
156+ .mask 0x00080000
157+ addik r1,r1,-8
158+ swi r19,r1,4
159+ addk r19,r1,r0
160+ addk r1,r19,r0
161+ lwi r19,r1,4
162+ addik r1,r1,8
163+ rtsd r15,8
164+ nop # Unfilled delay slot
165+
166+ .end __def_start
167+$Lfe1:
168+ .size __def_start,$Lfe1-__def_start
169+ .align 2
170+ .globl main
171+ .ent main
172+ .type main, @function
173+main:
174+ .frame r19,32,r15 # vars= 0, regs= 1, args= 24
175+ .mask 0x00088000
176+ addik r1,r1,-32
177+ swi r15,r1,0
178+ swi r19,r1,28
179+ addk r19,r1,r0
180+ brlid r15,test_start
181+ nop # Unfilled delay slot
182+
183+ brlid r15,test_start_strong
184+ nop # Unfilled delay slot
185+
186+ addk r3,r0,r0
187+ lwi r15,r1,0
188+ addk r1,r19,r0
189+ lwi r19,r1,28
190+ addik r1,r1,32
191+ rtsd r15,8
192+ nop # Unfilled delay slot
193+
194+ .end main
195+$Lfe2:
196+ .size main,$Lfe2-main
197+ .weakext test_start
198+ test_start = __def_start
199+ .globl test_start_strong
200+ test_start_strong = __def_start
201diff --git a/gas/testsuite/gas/microblaze/special_reg.d b/gas/testsuite/gas/microblaze/special_reg.d
202new file mode 100644
203index 0000000..aad0131
204--- /dev/null
205+++ b/gas/testsuite/gas/microblaze/special_reg.d
206@@ -0,0 +1,14 @@
207+#as:
208+#objdump: -ds
209+
210+.*: file format .*
211+
212+Contents of section .text:
213+ 0000 9409d000 6c00d000 001ff800 ....l.......
214+
215+Disassembly of section .text:
216+
217+00000000 <.text>:
218+ 0: 9409d000 mts rpid, r9
219+ 4: 6c00d000 tnput rfsl0
220+ 8: 001ff800 add r0, r31, r31
221diff --git a/gas/testsuite/gas/microblaze/special_reg.exp b/gas/testsuite/gas/microblaze/special_reg.exp
222new file mode 100644
223index 0000000..4824f76
224--- /dev/null
225+++ b/gas/testsuite/gas/microblaze/special_reg.exp
226@@ -0,0 +1,5 @@
227+# MicroBlaze test for special register.
228+
229+if [istarget microblaze*-*-*] {
230+ run_dump_test "special_reg"
231+}
232diff --git a/gas/testsuite/gas/microblaze/special_reg.s b/gas/testsuite/gas/microblaze/special_reg.s
233new file mode 100644
234index 0000000..d92ee4d
235--- /dev/null
236+++ b/gas/testsuite/gas/microblaze/special_reg.s
237@@ -0,0 +1,3 @@
238+ mts rpid, r9
239+ tnput rfsl0
240+ add r0, r31, r31
241--
2421.7.5.4
243
diff --git a/recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch b/recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch
new file mode 100644
index 00000000..e8ee3673
--- /dev/null
+++ b/recipes-devtools/binutils/files/0002-297486a0aa2156f8a9a03ec95d43fe4ee0cb159a.patch
@@ -0,0 +1,30 @@
1From 297486a0aa2156f8a9a03ec95d43fe4ee0cb159a Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Wed, 7 Nov 2012 15:36:08 +0000
4Subject: 2012-11-07 David Holsgrove <david.holsgrove@xilinx.com>
5
6 * config/tc-microblaze.c: Remove special register condition check
7 for INST_TYPE_RFSL related instructions.
8
92012-11-07 David Holsgrove <david.holsgrove@xilinx.com>
10
11 * testsuite/gas/microblaze/special_reg.exp: Add test case.
12 * testsuite/gas/microblaze/special_reg.s: Likewise.
13 * testsuite/gas/microblaze/special_reg.d: Likewise.
14
15Upstream-Status: Backport
16
17diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
18index 86ac90b..de0efda 100644
19--- a/gas/config/tc-microblaze.c
20+++ b/gas/config/tc-microblaze.c
21@@ -1198,9 +1198,6 @@ md_assemble (char * str)
22 as_fatal (_("Error in statement syntax"));
23 immed = 0;
24 }
25- /* Check for spl registers. */
26- if (check_spl_reg (&reg1))
27- as_fatal (_("Cannot use special register with this instruction"));
28 inst |= (immed << IMM_LOW) & RFSL_MASK;
29 output = frag_more (isize);
30 break;
diff --git a/recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch b/recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch
new file mode 100644
index 00000000..1504b5aa
--- /dev/null
+++ b/recipes-devtools/binutils/files/0003-eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e.patch
@@ -0,0 +1,632 @@
1From eb7b10e71f9569f0b90e0c6c128121ecf14c2e8e Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Fri, 9 Nov 2012 16:24:57 +0000
4Subject: Add microblazeel target support to bfd, gas and ld.
5
6binutils/bfd/Changelog
7
8 2012-11-09 Edgar E. Iglesias <edgar.iglesias@gmail.com>
9
10 * config.bfd: Add microblazeel-*-*
11 * configure.in: Likewise.
12 * configure: Regenerate.
13 * elf32-microblaze.c (microblaze_elf_relocate_section):
14 Add endian awareness.
15 (microblaze_elf_merge_private_bfd_data): New.
16 (microblaze_bfd_write_imm_value_32): New.
17 (microblaze_bfd_write_imm_value_64): New.
18 (microblaze_elf_relax_section): Add endian awareness.
19 (microblaze_elf_add_symbol_hook): Define TARGET_LITTLE_NAME,
20 TARGET_LITTLE_SYM and bfd_elf32_bfd_merge_private_bfd_data.
21 * targets.c: Add bfd target bfd_elf32_microblazeel_vec.
22
23binutils/gas/Changelog
24
25 2012-11-09 Edgar E. Iglesias <edgar.iglesias@gmail.com>
26
27 * tc-microblaze.c (md_longopts): Define OPTION_EB and
28 OPTION_EL for target.
29 (md_parse_option): Likewise.
30 * tc-microblaze.h: Set elf32-microblazeel if not
31 target_big_endian for TARGET_FORMAT.
32 * configure.tgt: Add microblazeel and set endian per target.
33
34binutils/gas/testsuite/Changelog
35
36 2012-11-09 David Holsgrove <david.holsgrove@xilinx.com>
37
38 * gas/microblaze/endian.exp: New file - endian
39 testcase for microblaze / microblazeel.
40 * gas/microblaze/endian.s: Likewise.
41 * gas/microblaze/endian_be.d: Likewise.
42 * gas/microblaze/endian_le.d: Likewise.
43 * gas/microblaze/endian_le_elf.d: Likewise.
44 * gas/microblaze/reloc_sym.d: Update to accept targets
45 other than elf32-microblaze.
46 * gas/microblaze/special_reg.d: Likewise.
47
48binutils/ld/Changelog
49
50 2012-11-09 Edgar E. Iglesias <edgar.iglesias@gmail.com>
51
52 * Makefile.am: Add eelf32microblazeel.c and eelf32mbel_linux.c.
53 * Makefile.in: Regenerated.
54 * configure.tgt: Add microblazeel and set endian per target.
55 * emulparams/elf32mb_linux.sh: Add OUTPUT_FORMAT.
56 * emulparams/elf32microblaze.sh: Likewise.
57 * emulparams/elf32mbel_linux.sh: New file.
58 * emulparams/elf32microblazeel.sh: Likewise.
59
60Upstream-Status: Backport
61
62diff --git a/bfd/config.bfd b/bfd/config.bfd
63index 7def642..e59ab25 100644
64--- a/bfd/config.bfd
65+++ b/bfd/config.bfd
66@@ -916,8 +916,14 @@ case "${targ}" in
67 targ_selvecs=bfd_elf32_mep_little_vec
68 ;;
69
70+ microblazeel*-*)
71+ targ_defvec=bfd_elf32_microblazeel_vec
72+ targ_selvecs=bfd_elf32_microblaze_vec
73+ ;;
74+
75 microblaze*-*)
76 targ_defvec=bfd_elf32_microblaze_vec
77+ targ_selvecs=bfd_elf32_microblazeel_vec
78 ;;
79
80 mips*-big-*)
81diff --git a/bfd/configure b/bfd/configure
82index 43bff03..7b073cc 100755
83--- a/bfd/configure
84+++ b/bfd/configure
85@@ -15283,6 +15283,7 @@ do
86 bfd_elf32_mcore_little_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
87 bfd_elf32_mep_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
88 bfd_elf32_mep_little_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
89+ bfd_elf32_microblazeel_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
90 bfd_elf32_microblaze_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
91 bfd_elf32_mn10200_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;;
92 bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
93diff --git a/bfd/configure.in b/bfd/configure.in
94index f7e3929..78f2744 100644
95--- a/bfd/configure.in
96+++ b/bfd/configure.in
97@@ -764,6 +764,7 @@ do
98 bfd_elf32_mcore_little_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
99 bfd_elf32_mep_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
100 bfd_elf32_mep_little_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
101+ bfd_elf32_microblazeel_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
102 bfd_elf32_microblaze_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
103 bfd_elf32_mn10200_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;;
104 bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
105diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
106index c000424..be2de13 100644
107--- a/bfd/elf32-microblaze.c
108+++ b/bfd/elf32-microblaze.c
109@@ -702,6 +702,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
110 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
111 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
112 Elf_Internal_Rela *rel, *relend;
113+ int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
114 /* Assume success. */
115 bfd_boolean ret = TRUE;
116 asection *sreloc;
117@@ -933,9 +934,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
118 + offset + INST_WORD_SIZE);
119 relocation += addend;
120 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
121- contents + offset + 2);
122+ contents + offset + endian);
123 bfd_put_16 (input_bfd, relocation & 0xffff,
124- contents + offset + 2 + INST_WORD_SIZE);
125+ contents + offset + endian + INST_WORD_SIZE);
126 break;
127
128 case (int) R_MICROBLAZE_PLT_64:
129@@ -952,9 +953,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
130 + input_section->output_offset
131 + offset + INST_WORD_SIZE);
132 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
133- contents + offset + 2);
134+ contents + offset + endian);
135 bfd_put_16 (input_bfd, immediate & 0xffff,
136- contents + offset + 2 + INST_WORD_SIZE);
137+ contents + offset + endian + INST_WORD_SIZE);
138 }
139 else
140 {
141@@ -963,9 +964,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
142 + offset + INST_WORD_SIZE);
143 immediate = relocation;
144 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
145- contents + offset + 2);
146+ contents + offset + endian);
147 bfd_put_16 (input_bfd, immediate & 0xffff,
148- contents + offset + 2 + INST_WORD_SIZE);
149+ contents + offset + endian + INST_WORD_SIZE);
150 }
151 break;
152 }
153@@ -1031,9 +1032,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
154 abort (); /* ??? */
155 }
156 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
157- contents + offset + 2);
158+ contents + offset + endian);
159 bfd_put_16 (input_bfd, relocation & 0xffff,
160- contents + offset + 2 + INST_WORD_SIZE);
161+ contents + offset + endian + INST_WORD_SIZE);
162 break;
163 }
164
165@@ -1048,8 +1049,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
166 immediate = relocation;
167 lo = immediate & 0x0000ffff;
168 high = (immediate >> 16) & 0x0000ffff;
169- bfd_put_16 (input_bfd, high, contents + offset + 2);
170- bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + 2);
171+ bfd_put_16 (input_bfd, high, contents + offset + endian);
172+ bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
173 break;
174 }
175
176@@ -1082,9 +1083,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
177 + input_section->output_offset
178 + offset + INST_WORD_SIZE);
179 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
180- contents + offset + 2);
181+ contents + offset + endian);
182 bfd_put_16 (input_bfd, relocation & 0xffff,
183- contents + offset + 2 + INST_WORD_SIZE);
184+ contents + offset + endian + INST_WORD_SIZE);
185 }
186 break;
187 }
188@@ -1176,9 +1177,9 @@ microblaze_elf_relocate_section (bfd *output_bfd,
189 + input_section->output_offset
190 + offset + INST_WORD_SIZE);
191 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
192- contents + offset + 2);
193+ contents + offset + endian);
194 bfd_put_16 (input_bfd, relocation & 0xffff,
195- contents + offset + 2 + INST_WORD_SIZE);
196+ contents + offset + endian + INST_WORD_SIZE);
197 }
198 break;
199 }
200@@ -1253,6 +1254,21 @@ microblaze_elf_relocate_section (bfd *output_bfd,
201
202 return ret;
203 }
204+
205+/* Merge backend specific data from an object file to the output
206+ object file when linking.
207+
208+ Note: We only use this hook to catch endian mismatches. */
209+static bfd_boolean
210+microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
211+{
212+ /* Check if we have the same endianess. */
213+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
214+ return FALSE;
215+
216+ return TRUE;
217+}
218+
219
220 /* Calculate fixup value for reference. */
221
222@@ -1275,6 +1291,36 @@ calc_fixup (bfd_vma addr, asection *sec)
223 return fixup;
224 }
225
226+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
227+ a 32-bit instruction. */
228+static void
229+microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
230+{
231+ unsigned long instr = bfd_get_32 (abfd, bfd_addr);
232+ instr &= ~0x0000ffff;
233+ instr |= (val & 0x0000ffff);
234+ bfd_put_32 (abfd, instr, bfd_addr);
235+}
236+
237+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
238+ two consecutive 32-bit instructions. */
239+static void
240+microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
241+{
242+ unsigned long instr_hi;
243+ unsigned long instr_lo;
244+
245+ instr_hi = bfd_get_32 (abfd, bfd_addr);
246+ instr_hi &= ~0x0000ffff;
247+ instr_hi |= ((val >> 16) & 0x0000ffff);
248+ bfd_put_32 (abfd, instr_hi, bfd_addr);
249+
250+ instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
251+ instr_lo &= ~0x0000ffff;
252+ instr_lo |= (val & 0x0000ffff);
253+ bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
254+}
255+
256 static bfd_boolean
257 microblaze_elf_relax_section (bfd *abfd,
258 asection *sec,
259@@ -1305,7 +1351,8 @@ microblaze_elf_relax_section (bfd *abfd,
260 /* Only do this for a text section. */
261 if (link_info->relocatable
262 || (sec->flags & SEC_RELOC) == 0
263- || (sec->reloc_count == 0))
264+ || (sec->reloc_count == 0)
265+ || (sec->flags & SEC_CODE) == 0)
266 return TRUE;
267
268 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
269@@ -1485,7 +1532,8 @@ microblaze_elf_relax_section (bfd *abfd,
270 efix = calc_fixup (target_address, sec);
271 irel->r_addend -= (efix - sfix);
272 /* Should use HOWTO. */
273- bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset + 2);
274+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
275+ irel->r_addend);
276 }
277 break;
278 case R_MICROBLAZE_64_NONE:
279@@ -1498,8 +1546,8 @@ microblaze_elf_relax_section (bfd *abfd,
280 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, sec);
281 efix = calc_fixup (target_address, sec);
282 irel->r_addend -= (efix - sfix);
283- bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset
284- + INST_WORD_SIZE + 2);
285+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
286+ + INST_WORD_SIZE, irel->r_addend);
287 }
288 break;
289 }
290@@ -1627,13 +1675,14 @@ microblaze_elf_relax_section (bfd *abfd,
291 }
292 }
293
294- immediate = (unsigned short) bfd_get_16 (abfd, ocontents +
295- irelscan->r_offset + 2);
296+ unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
297+ immediate = instr & 0x0000ffff;
298 target_address = immediate;
299 offset = calc_fixup (target_address, sec);
300 immediate -= offset;
301 irelscan->r_addend -= offset;
302- bfd_put_16 (abfd, immediate, ocontents + irelscan->r_offset + 2);
303+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
304+ irelscan->r_addend);
305 }
306 }
307
308@@ -1669,15 +1718,13 @@ microblaze_elf_relax_section (bfd *abfd,
309 elf_section_data (o)->this_hdr.contents = ocontents;
310 }
311 }
312- immediate = (unsigned short) (bfd_get_16 (abfd, ocontents
313- + irelscan->r_offset
314- + 2) << 16)
315- & 0xffff0000;
316- immediate += (unsigned short) (bfd_get_16 (abfd, ocontents
317- + irelscan->r_offset
318- + INST_WORD_SIZE + 2))
319- & 0x0000ffff;
320-
321+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
322+ + irelscan->r_offset);
323+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
324+ + irelscan->r_offset
325+ + INST_WORD_SIZE);
326+ immediate = (instr_hi & 0x0000ffff) << 16;
327+ immediate |= (instr_lo & 0x0000ffff);
328 offset = calc_fixup (irelscan->r_addend, sec);
329 immediate -= offset;
330 irelscan->r_addend -= offset;
331@@ -1715,22 +1762,19 @@ microblaze_elf_relax_section (bfd *abfd,
332 elf_section_data (o)->this_hdr.contents = ocontents;
333 }
334 }
335-
336- immediate = (unsigned short)
337- (bfd_get_16 (abfd, ocontents + irelscan->r_offset + 2) << 16)
338- & 0xffff0000;
339- immediate += (unsigned short)
340- (bfd_get_16 (abfd, ocontents + irelscan->r_offset
341- + INST_WORD_SIZE + 2))
342- & 0x0000ffff;
343+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
344+ + irelscan->r_offset);
345+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
346+ + irelscan->r_offset
347+ + INST_WORD_SIZE);
348+ immediate = (instr_hi & 0x0000ffff) << 16;
349+ immediate |= (instr_lo & 0x0000ffff);
350 target_address = immediate;
351 offset = calc_fixup (target_address, sec);
352 immediate -= offset;
353 irelscan->r_addend -= offset;
354- bfd_put_16 (abfd, ((immediate >> 16) & 0x0000ffff),
355- ocontents + irelscan->r_offset + 2);
356- bfd_put_16 (abfd, (immediate & 0x0000ffff),
357- ocontents + irelscan->r_offset + INST_WORD_SIZE + 2);
358+ microblaze_bfd_write_imm_value_64 (abfd, ocontents
359+ + irelscan->r_offset, immediate);
360 }
361 }
362 }
363@@ -1800,9 +1844,12 @@ microblaze_elf_relax_section (bfd *abfd,
364
365 if (sec->relax_count == 0)
366 {
367+ *again = FALSE;
368 free (sec->relax);
369 sec->relax = NULL;
370 }
371+ else
372+ *again = TRUE;
373 return TRUE;
374
375 error_return:
376@@ -3016,6 +3063,8 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
377 return TRUE;
378 }
379
380+#define TARGET_LITTLE_SYM bfd_elf32_microblazeel_vec
381+#define TARGET_LITTLE_NAME "elf32-microblazeel"
382
383 #define TARGET_BIG_SYM bfd_elf32_microblaze_vec
384 #define TARGET_BIG_NAME "elf32-microblaze"
385@@ -3032,6 +3081,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
386 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
387 #define elf_backend_relocate_section microblaze_elf_relocate_section
388 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
389+#define bfd_elf32_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
390 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
391
392 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
393diff --git a/bfd/targets.c b/bfd/targets.c
394index 621bf8d..442cb8f 100644
395--- a/bfd/targets.c
396+++ b/bfd/targets.c
397@@ -659,6 +659,7 @@ extern const bfd_target bfd_elf32_mcore_big_vec;
398 extern const bfd_target bfd_elf32_mcore_little_vec;
399 extern const bfd_target bfd_elf32_mep_vec;
400 extern const bfd_target bfd_elf32_mep_little_vec;
401+extern const bfd_target bfd_elf32_microblazeel_vec;
402 extern const bfd_target bfd_elf32_microblaze_vec;
403 extern const bfd_target bfd_elf32_mn10200_vec;
404 extern const bfd_target bfd_elf32_mn10300_vec;
405diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
406index de0efda..04dfa1e 100644
407--- a/gas/config/tc-microblaze.c
408+++ b/gas/config/tc-microblaze.c
409@@ -35,6 +35,9 @@
410 #define streq(a,b) (strcmp (a, b) == 0)
411 #endif
412
413+#define OPTION_EB (OPTION_MD_BASE + 0)
414+#define OPTION_EL (OPTION_MD_BASE + 1)
415+
416 void microblaze_generate_symbol (char *sym);
417 static bfd_boolean check_spl_reg (unsigned *);
418
419@@ -1707,6 +1710,8 @@ const char * md_shortopts = "";
420
421 struct option md_longopts[] =
422 {
423+ {"EB", no_argument, NULL, OPTION_EB},
424+ {"EL", no_argument, NULL, OPTION_EL},
425 { NULL, no_argument, NULL, 0}
426 };
427
428@@ -2304,6 +2309,12 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
429 {
430 switch (c)
431 {
432+ case OPTION_EB:
433+ target_big_endian = 1;
434+ break;
435+ case OPTION_EL:
436+ target_big_endian = 0;
437+ break;
438 default:
439 return 0;
440 }
441diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h
442index db8d227..0651040 100644
443--- a/gas/config/tc-microblaze.h
444+++ b/gas/config/tc-microblaze.h
445@@ -23,8 +23,10 @@
446 #define TC_MICROBLAZE 1
447
448 #define TARGET_ARCH bfd_arch_microblaze
449+#ifndef TARGET_BYTES_BIG_ENDIAN
450 /* Used to initialise target_big_endian. */
451 #define TARGET_BYTES_BIG_ENDIAN 1
452+#endif
453
454 #define IGNORE_NONSTANDARD_ESCAPES
455
456@@ -75,7 +77,7 @@ extern const struct relax_type md_relax_table[];
457
458 #ifdef OBJ_ELF
459
460-#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblaze-little")
461+#define TARGET_FORMAT (target_big_endian ? "elf32-microblaze" : "elf32-microblazeel")
462
463 #define ELF_TC_SPECIAL_SECTIONS \
464 { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
465diff --git a/gas/configure.tgt b/gas/configure.tgt
466index ff4cb3f..774031e 100644
467--- a/gas/configure.tgt
468+++ b/gas/configure.tgt
469@@ -57,7 +57,8 @@ case ${cpu} in
470 m6811|m6812|m68hc12) cpu_type=m68hc11 ;;
471 m683??) cpu_type=m68k ;;
472 mep) cpu_type=mep endian=little ;;
473- microblaze*) cpu_type=microblaze ;;
474+ microblazeel*) cpu_type=microblaze endian=little;;
475+ microblaze*) cpu_type=microblaze endian=big;;
476 mips*el) cpu_type=mips endian=little ;;
477 mips*) cpu_type=mips endian=big ;;
478 mt) cpu_type=mt endian=big ;;
479diff --git a/gas/testsuite/gas/microblaze/reloc_sym.d b/gas/testsuite/gas/microblaze/reloc_sym.d
480index 212d0bb..571ffe1 100644
481--- a/gas/testsuite/gas/microblaze/reloc_sym.d
482+++ b/gas/testsuite/gas/microblaze/reloc_sym.d
483@@ -1,6 +1,5 @@
484
485-reloc_sym.x: file format elf32-microblaze
486-
487+.*: +file format .*
488
489 Disassembly of section .text:
490
491diff --git a/gas/testsuite/gas/microblaze/special_reg.d b/gas/testsuite/gas/microblaze/special_reg.d
492index aad0131..c2041fd 100644
493--- a/gas/testsuite/gas/microblaze/special_reg.d
494+++ b/gas/testsuite/gas/microblaze/special_reg.d
495@@ -1,10 +1,7 @@
496 #as:
497-#objdump: -ds
498+#objdump: -d
499
500-.*: file format .*
501-
502-Contents of section .text:
503- 0000 9409d000 6c00d000 001ff800 ....l.......
504+.*: +file format .*
505
506 Disassembly of section .text:
507
508diff --git a/ld/Makefile.am b/ld/Makefile.am
509index 4c692ea..f6f814f 100644
510--- a/ld/Makefile.am
511+++ b/ld/Makefile.am
512@@ -237,6 +237,7 @@ ALL_EMULATION_SOURCES = \
513 eelf32mb_linux.c \
514 eelf32mcore.c \
515 eelf32mep.c \
516+ eelf32microblazeel.c \
517 eelf32microblaze.c \
518 eelf32mipswindiss.c \
519 eelf32moxie.c \
520@@ -1107,6 +1108,9 @@ eelf32m32c.c: $(srcdir)/emulparams/elf32m32c.sh \
521 $(ELF_DEPS) $(srcdir)/emultempl/needrelax.em \
522 $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
523 ${GENSCRIPTS} elf32m32c "$(tdir_m32c)"
524+eelf32mbel_linux.c: $(srcdir)/emulparams/elf32mbel_linux.sh \
525+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
526+ ${GENSCRIPTS} elf32mbel_linux "$(tdir_microblazeel)"
527 eelf32mb_linux.c: $(srcdir)/emulparams/elf32mb_linux.sh \
528 $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
529 ${GENSCRIPTS} elf32mb_linux "$(tdir_microblaze)"
530@@ -1116,6 +1120,9 @@ eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \
531 eelf32mep.c: $(srcdir)/emulparams/elf32mep.sh \
532 $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/mep.sc ${GEN_DEPENDS}
533 ${GENSCRIPTS} elf32mep "$(tdir_mep)"
534+eelf32microblazeel.c: $(srcdir)/emulparams/elf32microblazeel.sh \
535+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
536+ ${GENSCRIPTS} elf32microblazeel "$(tdir_microblazeel)"
537 eelf32microblaze.c: $(srcdir)/emulparams/elf32microblaze.sh \
538 $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
539 ${GENSCRIPTS} elf32microblaze "$(tdir_microblaze)"
540diff --git a/ld/Makefile.in b/ld/Makefile.in
541index a675d01..fb0c21e 100644
542--- a/ld/Makefile.in
543+++ b/ld/Makefile.in
544@@ -544,6 +544,7 @@ ALL_EMULATION_SOURCES = \
545 eelf32mb_linux.c \
546 eelf32mcore.c \
547 eelf32mep.c \
548+ eelf32microblazeel.c \
549 eelf32microblaze.c \
550 eelf32mipswindiss.c \
551 eelf32moxie.c \
552@@ -1166,6 +1167,7 @@ distclean-compile:
553 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mcore.Po@am__quote@
554 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mep.Po@am__quote@
555 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblaze.Po@am__quote@
556+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblazeel.Po@am__quote@
557 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Po@am__quote@
558 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32moxie.Po@am__quote@
559 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mt.Po@am__quote@
560@@ -2577,6 +2579,9 @@ eelf32m32c.c: $(srcdir)/emulparams/elf32m32c.sh \
561 $(ELF_DEPS) $(srcdir)/emultempl/needrelax.em \
562 $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
563 ${GENSCRIPTS} elf32m32c "$(tdir_m32c)"
564+eelf32mbel_linux.c: $(srcdir)/emulparams/elf32mbel_linux.sh \
565+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
566+ ${GENSCRIPTS} elf32mbel_linux "$(tdir_microblazeel)"
567 eelf32mb_linux.c: $(srcdir)/emulparams/elf32mb_linux.sh \
568 $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
569 ${GENSCRIPTS} elf32mb_linux "$(tdir_microblaze)"
570@@ -2586,6 +2591,9 @@ eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \
571 eelf32mep.c: $(srcdir)/emulparams/elf32mep.sh \
572 $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/mep.sc ${GEN_DEPENDS}
573 ${GENSCRIPTS} elf32mep "$(tdir_mep)"
574+eelf32microblazeel.c: $(srcdir)/emulparams/elf32microblazeel.sh \
575+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
576+ ${GENSCRIPTS} elf32microblazeel "$(tdir_microblazeel)"
577 eelf32microblaze.c: $(srcdir)/emulparams/elf32microblaze.sh \
578 $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfmicroblaze.sc ${GEN_DEPENDS}
579 ${GENSCRIPTS} elf32microblaze "$(tdir_microblaze)"
580diff --git a/ld/configure.tgt b/ld/configure.tgt
581index 0e62b52..9f0025a 100644
582--- a/ld/configure.tgt
583+++ b/ld/configure.tgt
584@@ -395,9 +395,18 @@ mcore-*-pe) targ_emul=mcorepe ;
585 mcore-*-elf) targ_emul=elf32mcore
586 ;;
587 mep-*-elf) targ_emul=elf32mep ;;
588-microblaze*-linux*)
589- targ_emul="elf32mb_linux" ;;
590-microblaze*) targ_emul=elf32microblaze ;;
591+microblazeel*-linux*) targ_emul="elf32mbel_linux"
592+ targ_extra_emuls="elf32mb_linux"
593+ ;;
594+microblaze*-linux*) targ_emul="elf32mb_linux"
595+ targ_extra_emuls="elf32mbel_linux"
596+ ;;
597+microblazeel*) targ_emul=elf32microblazeel
598+ targ_extra_emuls=elf32microblaze
599+ ;;
600+microblaze*) targ_emul=elf32microblaze
601+ targ_extra_emuls=elf32microblazeel
602+ ;;
603 mips*-*-pe) targ_emul=mipspe ;
604 targ_extra_ofiles="deffilep.o pe-dll.o" ;;
605 mips*-dec-ultrix*) targ_emul=mipslit ;;
606diff --git a/ld/emulparams/elf32mb_linux.sh b/ld/emulparams/elf32mb_linux.sh
607index f26f1a0..bb60d1f 100644
608--- a/ld/emulparams/elf32mb_linux.sh
609+++ b/ld/emulparams/elf32mb_linux.sh
610@@ -1,5 +1,7 @@
611 SCRIPT_NAME=elf
612 OUTPUT_FORMAT="elf32-microblaze"
613+BIG_OUTPUT_FORMAT="elf32-microblaze"
614+LITTLE_OUTPUT_FORMAT="elf32-microblazeel"
615 TEXT_START_ADDR=0x10000000
616 NONPAGED_TEXT_START_ADDR=0x28
617 ALIGNMENT=4
618diff --git a/ld/emulparams/elf32microblaze.sh b/ld/emulparams/elf32microblaze.sh
619index ccc20d1..1f80447 100644
620--- a/ld/emulparams/elf32microblaze.sh
621+++ b/ld/emulparams/elf32microblaze.sh
622@@ -1,5 +1,7 @@
623 SCRIPT_NAME=elfmicroblaze
624 OUTPUT_FORMAT="elf32-microblaze"
625+BIG_OUTPUT_FORMAT="elf32-microblaze"
626+LITTLE_OUTPUT_FORMAT="elf32-microblazeel"
627 #TEXT_START_ADDR=0
628 NONPAGED_TEXT_START_ADDR=0x28
629 ALIGNMENT=4
630--
6311.7.5.4
632
diff --git a/recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch b/recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch
new file mode 100644
index 00000000..e3db8ea4
--- /dev/null
+++ b/recipes-devtools/binutils/files/0004-58deb49b33812b048a1061553c1ca6f010af59f4.patch
@@ -0,0 +1,63 @@
1From 58deb49b33812b048a1061553c1ca6f010af59f4 Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Fri, 9 Nov 2012 22:43:28 +0000
4Subject: Files missing from previous commit.
5
6Upstream-Status: Backport
7
8diff --git a/ld/emulparams/elf32mbel_linux.sh b/ld/emulparams/elf32mbel_linux.sh
9new file mode 100644
10index 0000000..2980e82
11--- /dev/null
12+++ b/ld/emulparams/elf32mbel_linux.sh
13@@ -0,0 +1,18 @@
14+SCRIPT_NAME=elf
15+OUTPUT_FORMAT="elf32-microblazeel"
16+BIG_OUTPUT_FORMAT="elf32-microblaze"
17+LITTLE_OUTPUT_FORMAT="elf32-microblazeel"
18+TEXT_START_ADDR=0x10000000
19+NONPAGED_TEXT_START_ADDR=0x28
20+ALIGNMENT=4
21+MAXPAGESIZE=0x1000
22+COMMONPAGESIZE=0x1000
23+ARCH=microblaze
24+
25+NOP=0x80000000
26+
27+TEMPLATE_NAME=elf32
28+GENERATE_SHLIB_SCRIPT=yes
29+GENERATE_PIE_SCRIPT=yes
30+NO_SMALL_DATA=yes
31+SEPARATE_GOTPLT=12
32diff --git a/ld/emulparams/elf32microblazeel.sh b/ld/emulparams/elf32microblazeel.sh
33new file mode 100644
34index 0000000..86268b0
35--- /dev/null
36+++ b/ld/emulparams/elf32microblazeel.sh
37@@ -0,0 +1,23 @@
38+SCRIPT_NAME=elfmicroblaze
39+OUTPUT_FORMAT="elf32-microblazeel"
40+BIG_OUTPUT_FORMAT="elf32-microblaze"
41+LITTLE_OUTPUT_FORMAT="elf32-microblazeel"
42+#TEXT_START_ADDR=0
43+NONPAGED_TEXT_START_ADDR=0x28
44+ALIGNMENT=4
45+MAXPAGESIZE=4
46+ARCH=microblaze
47+EMBEDDED=yes
48+
49+NOP=0x80000000
50+
51+# Hmmm, there's got to be a better way. This sets the stack to the
52+# top of the simulator memory (2^19 bytes).
53+#PAGE_SIZE=0x1000
54+#DATA_ADDR=0x10000
55+#OTHER_RELOCATING_SECTIONS='.stack 0x7000 : { _stack = .; *(.stack) }'
56+#$@{RELOCATING+ PROVIDE (__stack = 0x7000);@}
57+#OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = _end + 0x1000);'
58+
59+TEMPLATE_NAME=elf32
60+#GENERATE_SHLIB_SCRIPT=yes
61--
621.7.5.4
63
diff --git a/recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch b/recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch
new file mode 100644
index 00000000..977fbfcd
--- /dev/null
+++ b/recipes-devtools/binutils/files/0005-de1b485c223f0799e7f2f88d2fa6c010191bd1ed.patch
@@ -0,0 +1,89 @@
1From de1b485c223f0799e7f2f88d2fa6c010191bd1ed Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Mon, 12 Nov 2012 00:23:25 +0000
4Subject: Add missing test cases. * gas/microblaze/endian.exp: New
5 file - endian testcase for microblaze / microblazeel. *
6 gas/microblaze/endian.s: Likewise. *
7 gas/microblaze/endian_be.d: Likewise. *
8 gas/microblaze/endian_le.d: Likewise. *
9 gas/microblaze/endian_le_elf.d: Likewise.
10
11Upstream-Status: Backport
12
13diff --git a/gas/testsuite/gas/microblaze/endian.exp b/gas/testsuite/gas/microblaze/endian.exp
14new file mode 100644
15index 0000000..2ec2112
16--- /dev/null
17+++ b/gas/testsuite/gas/microblaze/endian.exp
18@@ -0,0 +1,12 @@
19+# MicroBlaze test for special register.
20+
21+if [istarget microblaze-*-*] {
22+ run_dump_test "endian_be"
23+ if [istarget microblaze-*-elf] {
24+ run_dump_test "endian_le_elf"
25+ }
26+}
27+
28+if [istarget microblazeel-*-*] {
29+ run_dump_test "endian_le"
30+}
31diff --git a/gas/testsuite/gas/microblaze/endian.s b/gas/testsuite/gas/microblaze/endian.s
32new file mode 100644
33index 0000000..1274d89
34--- /dev/null
35+++ b/gas/testsuite/gas/microblaze/endian.s
36@@ -0,0 +1,5 @@
37+ .text
38+start:
39+ addi r1,r0,1234
40+ .long 0x12345678
41+ .word 0x1234, 0
42diff --git a/gas/testsuite/gas/microblaze/endian_be.d b/gas/testsuite/gas/microblaze/endian_be.d
43new file mode 100644
44index 0000000..266d3f3
45--- /dev/null
46+++ b/gas/testsuite/gas/microblaze/endian_be.d
47@@ -0,0 +1,9 @@
48+#as:
49+#objdump: -s
50+#name: MicroBlaze Big Endian
51+#source: endian.s
52+
53+.*: file format elf32-microblaze
54+
55+Contents of section .text:
56+ 0000 202004d2 12345678 00001234 00000000 ...4Vx...4....
57diff --git a/gas/testsuite/gas/microblaze/endian_le.d b/gas/testsuite/gas/microblaze/endian_le.d
58new file mode 100644
59index 0000000..9aa5931
60--- /dev/null
61+++ b/gas/testsuite/gas/microblaze/endian_le.d
62@@ -0,0 +1,9 @@
63+#as:
64+#objdump: -s
65+#name: MicroBlaze Little Endian
66+#source: endian.s
67+
68+.*: file format elf32-microblazeel
69+
70+Contents of section .text:
71+ 0000 d2042020 78563412 34120000 00000000 .. xV4.4.......
72diff --git a/gas/testsuite/gas/microblaze/endian_le_elf.d b/gas/testsuite/gas/microblaze/endian_le_elf.d
73new file mode 100644
74index 0000000..e3647b6
75--- /dev/null
76+++ b/gas/testsuite/gas/microblaze/endian_le_elf.d
77@@ -0,0 +1,9 @@
78+#as: -EL
79+#objdump: -s
80+#name: MicroBlaze Little Endian
81+#source: endian.s
82+
83+.*: file format elf32-microblazeel
84+
85+Contents of section .text:
86+ 0000 d2042020 78563412 34120000 00000000 .. xV4.4.......
87--
881.7.5.4
89
diff --git a/recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch b/recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch
new file mode 100644
index 00000000..c3961afe
--- /dev/null
+++ b/recipes-devtools/binutils/files/0006-1e6eff13a8f06601a76ca70b9b74651016ef042d.patch
@@ -0,0 +1,143 @@
1From 1e6eff13a8f06601a76ca70b9b74651016ef042d Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Wed, 14 Nov 2012 16:19:28 +0000
4Subject: Add the endian reversing versions of load/store instructions;
5
62012-11-14 Edgar E. Iglesias <edgar.iglesias@gmail.com>
7
8 * microblaze-opc.h: Increase MAX_OPCODES (op_code_struct): add lbur,
9 lhur, lwr, sbr, shr, swr
10 * microblaze-opcm.h (microblaze_instr): add lbur, lhur, lwr, sbr, shr,
11 swr
12
132012-11-14 David Holsgrove <david.holsgrove@xilinx.com>
14
15 * gas/microblaze/allinsn.exp: New file - test newly added opcodes
16 * gas/microblaze/allinsn.s: Likewise
17 * gas/microblaze/allinsn.d: Likewise
18
19Upstream-Status: Backport
20
21diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d
22new file mode 100644
23index 0000000..79064ba
24--- /dev/null
25+++ b/gas/testsuite/gas/microblaze/allinsn.d
26@@ -0,0 +1,24 @@
27+#as:
28+#objdump: -d
29+
30+.*: +file format .*
31+
32+Disassembly of section .text:
33+
34+00000000 <lbur>:
35+ 0: c0000200 lbur r0, r0, r0
36+
37+00000004 <lhur>:
38+ 4: c4000200 lhur r0, r0, r0
39+
40+00000008 <lwr>:
41+ 8: c8000200 lwr r0, r0, r0
42+
43+0000000c <sbr>:
44+ c: d0000200 sbr r0, r0, r0
45+
46+00000010 <shr>:
47+ 10: d4000200 shr r0, r0, r0
48+
49+00000014 <swr>:
50+ 14: d8000200 swr r0, r0, r0
51diff --git a/gas/testsuite/gas/microblaze/allinsn.exp b/gas/testsuite/gas/microblaze/allinsn.exp
52new file mode 100644
53index 0000000..d1b1dea
54--- /dev/null
55+++ b/gas/testsuite/gas/microblaze/allinsn.exp
56@@ -0,0 +1,5 @@
57+# MicroBlaze test for special register.
58+
59+if [istarget microblaze*-*-*] {
60+ run_dump_test "allinsn"
61+}
62diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s
63new file mode 100644
64index 0000000..8bb3ef5
65--- /dev/null
66+++ b/gas/testsuite/gas/microblaze/allinsn.s
67@@ -0,0 +1,27 @@
68+ .text
69+footext:
70+ .text
71+ .global lbur
72+lbur:
73+ lbur r0,r0,r0
74+ .text
75+ .global lhur
76+lhur:
77+ lhur r0,r0,r0
78+ .text
79+ .global lwr
80+lwr:
81+ lwr r0,r0,r0
82+ .text
83+ .global sbr
84+sbr:
85+ sbr r0,r0,r0
86+ .text
87+ .global shr
88+shr:
89+ shr r0,r0,r0
90+ .text
91+ .global swr
92+swr:
93+ swr r0,r0,r0
94+
95diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
96index 02ac83f..44c9d38 100644
97--- a/opcodes/microblaze-opc.h
98+++ b/opcodes/microblaze-opc.h
99@@ -96,7 +96,7 @@
100 #define DELAY_SLOT 1
101 #define NO_DELAY_SLOT 0
102
103-#define MAX_OPCODES 280
104+#define MAX_OPCODES 284
105
106 struct op_code_struct
107 {
108@@ -220,12 +220,18 @@ struct op_code_struct
109 {"bgei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBCA00000, OPCODE_MASK_H1, bgei, branch_inst },
110 {"bgeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBEA00000, OPCODE_MASK_H1, bgeid, branch_inst },
111 {"lbu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000000, OPCODE_MASK_H4, lbu, memory_load_inst },
112+ {"lbur", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000200, OPCODE_MASK_H4, lbur, memory_load_inst },
113 {"lhu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000000, OPCODE_MASK_H4, lhu, memory_load_inst },
114+ {"lhur", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000200, OPCODE_MASK_H4, lhur, memory_load_inst },
115 {"lw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000000, OPCODE_MASK_H4, lw, memory_load_inst },
116+ {"lwr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000200, OPCODE_MASK_H4, lwr, memory_load_inst },
117 {"lwx", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000400, OPCODE_MASK_H4, lwx, memory_load_inst },
118 {"sb", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000000, OPCODE_MASK_H4, sb, memory_store_inst },
119+ {"sbr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000200, OPCODE_MASK_H4, sbr, memory_store_inst },
120 {"sh", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000000, OPCODE_MASK_H4, sh, memory_store_inst },
121+ {"shr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000200, OPCODE_MASK_H4, shr, memory_store_inst },
122 {"sw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000000, OPCODE_MASK_H4, sw, memory_store_inst },
123+ {"swr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000200, OPCODE_MASK_H4, swr, memory_store_inst },
124 {"swx", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000400, OPCODE_MASK_H4, swx, memory_store_inst },
125 {"lbui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE0000000, OPCODE_MASK_H, lbui, memory_load_inst },
126 {"lhui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE4000000, OPCODE_MASK_H, lhui, memory_load_inst },
127diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
128index 10acacf..a3bec49 100644
129--- a/opcodes/microblaze-opcm.h
130+++ b/opcodes/microblaze-opcm.h
131@@ -36,7 +36,8 @@ enum microblaze_instr
132 bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
133 imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
134 brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
135- bgtid, bgei, bgeid, lbu, lhu, lw, lwx, sb, sh, sw, swx, lbui, lhui, lwi,
136+ bgtid, bgei, bgeid, lbu, lbur, lhu, lhur, lw, lwr, lwx, sb, sbr, sh,
137+ shr, sw, swr, swx, lbui, lhui, lwi,
138 sbi, shi, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv,
139 fcmp_lt, fcmp_eq, fcmp_le, fcmp_gt, fcmp_ne, fcmp_ge, fcmp_un, flt,
140 fint, fsqrt,
141--
1421.7.5.4
143
diff --git a/recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch b/recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch
new file mode 100644
index 00000000..caa22a0a
--- /dev/null
+++ b/recipes-devtools/binutils/files/0007-e2be436cc342d130ac0ba6b4a31724d71e473684.patch
@@ -0,0 +1,76 @@
1From e2be436cc342d130ac0ba6b4a31724d71e473684 Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Wed, 14 Nov 2012 16:45:00 +0000
4Subject: Add clz opcode.
5
6opcodes/
7 * microblaze-opc.h: Increase MAX_OPCODES (op_code_struct): add clz insn
8 * microblaze-opcm.h (microblaze_instr): add clz
9
10gas/testsuite/
11 * gas/microblaze/allinsn.s: Add clz insn
12 * gas/microblaze/allinsn.d: Likewise
13
14Upstream-Status: Backport
15
16diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d
17index 79064ba..c7854f1 100644
18--- a/gas/testsuite/gas/microblaze/allinsn.d
19+++ b/gas/testsuite/gas/microblaze/allinsn.d
20@@ -22,3 +22,6 @@ Disassembly of section .text:
21
22 00000014 <swr>:
23 14: d8000200 swr r0, r0, r0
24+
25+00000018 <clz>:
26+ 18: 900000e0 clz r0, r0
27diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s
28index 8bb3ef5..0e4271d 100644
29--- a/gas/testsuite/gas/microblaze/allinsn.s
30+++ b/gas/testsuite/gas/microblaze/allinsn.s
31@@ -24,4 +24,8 @@ shr:
32 .global swr
33 swr:
34 swr r0,r0,r0
35+ .text
36+ .global clz
37+clz:
38+ clz r0,r0
39
40diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
41index 44c9d38..132b951 100644
42--- a/opcodes/microblaze-opc.h
43+++ b/opcodes/microblaze-opc.h
44@@ -96,7 +96,7 @@
45 #define DELAY_SLOT 1
46 #define NO_DELAY_SLOT 0
47
48-#define MAX_OPCODES 284
49+#define MAX_OPCODES 285
50
51 struct op_code_struct
52 {
53@@ -394,6 +394,7 @@ struct op_code_struct
54 {"tneaputd", INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C0006E0, OPCODE_MASK_H34C, tneaputd, anyware_inst },
55 {"necaputd", INST_TYPE_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C000760, OPCODE_MASK_H34C, necaputd, anyware_inst },
56 {"tnecaputd", INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C0007E0, OPCODE_MASK_H34C, tnecaputd, anyware_inst },
57+ {"clz", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E0, OPCODE_MASK_H34, clz, special_inst },
58 {"", 0, 0, 0, 0, 0, 0, 0, 0},
59 };
60
61diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
62index a3bec49..58e6fd4 100644
63--- a/opcodes/microblaze-opcm.h
64+++ b/opcodes/microblaze-opcm.h
65@@ -25,7 +25,7 @@
66
67 enum microblaze_instr
68 {
69- add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, cmp, cmpu,
70+ add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu,
71 addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
72 mulh, mulhu, mulhsu,
73 idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
74--
751.7.5.4
76
diff --git a/recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch b/recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch
new file mode 100644
index 00000000..6da0bf6a
--- /dev/null
+++ b/recipes-devtools/binutils/files/0008-b5ab1aad93379ce5546b54321d2a7d577e8f0ccd.patch
@@ -0,0 +1,207 @@
1From b5ab1aad93379ce5546b54321d2a7d577e8f0ccd Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Wed, 14 Nov 2012 17:05:20 +0000
4Subject: opcodes/ * microblaze-opc.h: Define new instruction type
5 INST_TYPE_IMM5, update OPCODE_MASK_H13S, add OPCODE_MASK_HN,
6 define MIN_IMM5 / MAX_IMM5, and increase MAX_OPCODES.
7 (op_code_struct): add mbar and sleep * microblaze-opcm.h
8 (microblaze_instr): add mbar Define IMM_MBAR and IMM5_MBAR_MASK
9 * microblaze-dis.c: Add get_field_imm5_mbar
10 (print_insn_microblaze): Add support for INST_TYPE_IMM5 and
11 INST_TYPE_NONE
12
13gas/
14 * config/tc-microblaze.c (md_assemble): Add support for INST_TYPE_IMM5
15
16gas/testsuite/
17 * gas/microblaze/allinsn.s: Add mbar and sleep
18 * gas/microblaze/allinsn.d: Likewise
19
20Upstream-Status: Backport
21
22diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
23index 04dfa1e..b71383b 100644
24--- a/gas/config/tc-microblaze.c
25+++ b/gas/config/tc-microblaze.c
26@@ -1605,6 +1605,24 @@ md_assemble (char * str)
27 output = frag_more (isize);
28 break;
29
30+ case INST_TYPE_IMM5:
31+ if (strcmp(op_end, ""))
32+ op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
33+ else
34+ as_fatal(_("Error in statement syntax"));
35+ if (exp.X_op != O_constant) {
36+ as_warn(_("Symbol used as immediate for mbar instruction"));
37+ } else {
38+ output = frag_more (isize);
39+ immed = exp.X_add_number;
40+ }
41+ if (immed != (immed % 32)) {
42+ as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
43+ immed = immed % 32;
44+ }
45+ inst |= (immed << IMM_MBAR);
46+ break;
47+
48 default:
49 as_fatal (_("unimplemented opcode \"%s\""), name);
50 }
51diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d
52index c7854f1..ec14020 100644
53--- a/gas/testsuite/gas/microblaze/allinsn.d
54+++ b/gas/testsuite/gas/microblaze/allinsn.d
55@@ -25,3 +25,9 @@ Disassembly of section .text:
56
57 00000018 <clz>:
58 18: 900000e0 clz r0, r0
59+
60+0000001c <mbar>:
61+ 1c: b8420004 mbar 2
62+
63+00000020 <sleep>:
64+ 20: ba020004 sleep
65diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s
66index 0e4271d..582da17 100644
67--- a/gas/testsuite/gas/microblaze/allinsn.s
68+++ b/gas/testsuite/gas/microblaze/allinsn.s
69@@ -28,4 +28,12 @@ swr:
70 .global clz
71 clz:
72 clz r0,r0
73+ .text
74+ .global mbar
75+mbar:
76+ mbar 2
77+ .text
78+ .global sleep
79+sleep:
80+ sleep
81
82diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
83index bdbf831..e204e36 100644
84--- a/opcodes/microblaze-dis.c
85+++ b/opcodes/microblaze-dis.c
86@@ -65,6 +65,15 @@ get_field_imm5 (long instr)
87 }
88
89 static char *
90+get_field_imm5_mbar (long instr)
91+{
92+ char tmpstr[25];
93+
94+ sprintf(tmpstr, "%d", (short)((instr & IMM5_MBAR_MASK) >> IMM_MBAR));
95+ return(strdup(tmpstr));
96+}
97+
98+static char *
99 get_field_rfsl (long instr)
100 {
101 char tmpstr[25];
102@@ -374,6 +383,13 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
103 case INST_TYPE_RD_IMM15:
104 print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm15 (inst));
105 break;
106+ /* For mbar insn. */
107+ case INST_TYPE_IMM5:
108+ print_func (stream, "\t%s", get_field_imm5_mbar (inst));
109+ break;
110+ /* For mbar 16 or sleep insn. */
111+ case INST_TYPE_NONE:
112+ break;
113 /* For tuqula instruction */
114 case INST_TYPE_RD:
115 print_func (stream, "\t%s", get_field_rd (inst));
116diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
117index 132b951..0447fc5 100644
118--- a/opcodes/microblaze-opc.h
119+++ b/opcodes/microblaze-opc.h
120@@ -56,6 +56,9 @@
121 /* New insn type for t*put. */
122 #define INST_TYPE_RFSL 19
123
124+/* For mbar. */
125+#define INST_TYPE_IMM5 20
126+
127 #define INST_TYPE_NONE 25
128
129
130@@ -76,8 +79,8 @@
131 #define OPCODE_MASK_H2 0xFC1F0000 /* High 6 and bits 20-16. */
132 #define OPCODE_MASK_H12 0xFFFF0000 /* High 16. */
133 #define OPCODE_MASK_H4 0xFC0007FF /* High 6 and low 11 bits. */
134-#define OPCODE_MASK_H13S 0xFFE0EFF0 /* High 11 and 15:1 bits and last
135- nibble of last byte for spr. */
136+#define OPCODE_MASK_H13S 0xFFE0E7F0 /* High 11 16:18 21:27 bits, 19:20 bits
137+ and last nibble of last byte for spr. */
138 #define OPCODE_MASK_H23S 0xFC1FC000 /* High 6, 20-16 and 15:1 bits and last
139 nibble of last byte for spr. */
140 #define OPCODE_MASK_H34 0xFC00FFFF /* High 6 and low 16 bits. */
141@@ -92,11 +95,13 @@
142
143 /* New Mask for msrset, msrclr insns. */
144 #define OPCODE_MASK_H23N 0xFC1F8000 /* High 6 and bits 11 - 16. */
145+/* Mask for mbar insn. */
146+#define OPCODE_MASK_HN 0xFF020004 /* High 16 bits and bits 14, 29. */
147
148 #define DELAY_SLOT 1
149 #define NO_DELAY_SLOT 0
150
151-#define MAX_OPCODES 285
152+#define MAX_OPCODES 287
153
154 struct op_code_struct
155 {
156@@ -395,6 +400,8 @@ struct op_code_struct
157 {"necaputd", INST_TYPE_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C000760, OPCODE_MASK_H34C, necaputd, anyware_inst },
158 {"tnecaputd", INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x4C0007E0, OPCODE_MASK_H34C, tnecaputd, anyware_inst },
159 {"clz", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E0, OPCODE_MASK_H34, clz, special_inst },
160+ {"mbar", INST_TYPE_IMM5, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8020004, OPCODE_MASK_HN, mbar, special_inst },
161+ {"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. */
162 {"", 0, 0, 0, 0, 0, 0, 0, 0},
163 };
164
165@@ -412,5 +419,8 @@ char pvr_register_prefix[] = "rpvr";
166 #define MIN_IMM15 ((int) 0x0000)
167 #define MAX_IMM15 ((int) 0x7fff)
168
169+#define MIN_IMM5 ((int) 0x00000000)
170+#define MAX_IMM5 ((int) 0x0000001f)
171+
172 #endif /* MICROBLAZE_OPC */
173
174diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
175index 58e6fd4..867263e 100644
176--- a/opcodes/microblaze-opcm.h
177+++ b/opcodes/microblaze-opcm.h
178@@ -31,7 +31,7 @@ enum microblaze_instr
179 idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
180 ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor,
181 andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16,
182- wic, wdc, wdcclear, wdcflush, mts, mfs, br, brd,
183+ wic, wdc, wdcclear, wdcflush, mts, mfs, mbar, br, brd,
184 brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
185 bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
186 imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
187@@ -122,6 +122,7 @@ enum microblaze_instr_type
188 #define RA_LOW 16 /* Low bit for RA. */
189 #define RB_LOW 11 /* Low bit for RB. */
190 #define IMM_LOW 0 /* Low bit for immediate. */
191+#define IMM_MBAR 21 /* low bit for mbar instruction. */
192
193 #define RD_MASK 0x03E00000
194 #define RA_MASK 0x001F0000
195@@ -131,6 +132,9 @@ enum microblaze_instr_type
196 /* Imm mask for barrel shifts. */
197 #define IMM5_MASK 0x0000001F
198
199+/* Imm mask for mbar. */
200+#define IMM5_MBAR_MASK 0x03E00000
201+
202 /* FSL imm mask for get, put instructions. */
203 #define RFSL_MASK 0x000000F
204
205--
2061.7.5.4
207
diff --git a/recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch b/recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch
new file mode 100644
index 00000000..28b5672d
--- /dev/null
+++ b/recipes-devtools/binutils/files/0009-b66f7d905a679685476fbfbc793541adb8829a6c.patch
@@ -0,0 +1,149 @@
1From b66f7d905a679685476fbfbc793541adb8829a6c Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Wed, 21 Nov 2012 17:34:11 +0000
4Subject: Add stack high register and stack low register for MicroBlaze
5 hardware assisted stack protection, stores stack low / stack high
6 limits for detecting stack overflow / underflow
7
8binutils/opcodes
9 * microblaze-opcm.h: Add REG_SLR_MASK, REG_SHR_MASK, REG_SHR and REG_SLR
10 * microblaze-dis.c (get_field_special): Handle REG_SLR_MASK and REG_SHR_MASK
11binutils/gas
12 * config/tc-microblaze.c (parse_reg): Parse REG_SLR, REG_SHR
13binutils/gas
14 * gas/microblaze/allinsn.s: Test use of SHR, SLR
15 * gas/microblaze/allinsn.d: Likewise
16
17Upstream-Status: Backport
18
19diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
20index b71383b..5a427a0 100644
21--- a/gas/config/tc-microblaze.c
22+++ b/gas/config/tc-microblaze.c
23@@ -531,6 +531,17 @@ parse_reg (char * s, unsigned * reg)
24 }
25 return s;
26 }
27+ /* Stack protection registers. */
28+ else if (strncasecmp (s, "rshr", 4) == 0)
29+ {
30+ *reg = REG_SHR;
31+ return s + 4;
32+ }
33+ else if (strncasecmp (s, "rslr", 4) == 0)
34+ {
35+ *reg = REG_SLR;
36+ return s + 4;
37+ }
38 else
39 {
40 if (TOLOWER (s[0]) == 'r')
41@@ -760,6 +771,7 @@ check_spl_reg (unsigned * reg)
42 || (*reg == REG_PID) || (*reg == REG_ZPR)
43 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
44 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
45+ || (*reg == REG_SHR) || (*reg == REG_SLR)
46 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
47 return TRUE;
48
49@@ -1280,6 +1292,10 @@ md_assemble (char * str)
50 immed = opcode->immval_mask | REG_TLBLO_MASK;
51 else if (reg2 == REG_TLBHI)
52 immed = opcode->immval_mask | REG_TLBHI_MASK;
53+ else if (reg2 == REG_SHR)
54+ immed = opcode->immval_mask | REG_SHR_MASK;
55+ else if (reg2 == REG_SLR)
56+ immed = opcode->immval_mask | REG_SLR_MASK;
57 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
58 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
59 else
60@@ -1331,6 +1347,10 @@ md_assemble (char * str)
61 immed = opcode->immval_mask | REG_TLBHI_MASK;
62 else if (reg1 == REG_TLBSX)
63 immed = opcode->immval_mask | REG_TLBSX_MASK;
64+ else if (reg1 == REG_SHR)
65+ immed = opcode->immval_mask | REG_SHR_MASK;
66+ else if (reg1 == REG_SLR)
67+ immed = opcode->immval_mask | REG_SLR_MASK;
68 else
69 as_fatal (_("invalid value for special purpose register"));
70 inst |= (reg2 << RA_LOW) & RA_MASK;
71diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d
72index ec14020..4a03340 100644
73--- a/gas/testsuite/gas/microblaze/allinsn.d
74+++ b/gas/testsuite/gas/microblaze/allinsn.d
75@@ -31,3 +31,13 @@ Disassembly of section .text:
76
77 00000020 <sleep>:
78 20: ba020004 sleep
79+
80+00000024 <regslr>:
81+ 24: b0000000 imm 0
82+ 28: 31600000 addik r11, r0, 0
83+ 2c: 940bc800 mts rslr, r11
84+
85+00000030 <regshr>:
86+ 30: b0000000 imm 0
87+ 34: 31600000 addik r11, r0, 0
88+ 38: 940bc802 mts rshr, r11
89diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s
90index 582da17..437444f 100644
91--- a/gas/testsuite/gas/microblaze/allinsn.s
92+++ b/gas/testsuite/gas/microblaze/allinsn.s
93@@ -36,4 +36,14 @@ mbar:
94 .global sleep
95 sleep:
96 sleep
97+ .text
98+ .global regslr
99+regslr:
100+ la r11,r0,r0
101+ mts rslr,r11
102+ .text
103+ .global regshr
104+regshr:
105+ la r11,r0,r0
106+ mts rshr,r11
107
108diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
109index e204e36..7e3a546 100644
110--- a/opcodes/microblaze-dis.c
111+++ b/opcodes/microblaze-dis.c
112@@ -139,6 +139,12 @@ get_field_special (long instr, struct op_code_struct * op)
113 case REG_TLBSX_MASK :
114 strcpy (spr, "tlbsx");
115 break;
116+ case REG_SHR_MASK :
117+ strcpy (spr, "shr");
118+ break;
119+ case REG_SLR_MASK :
120+ strcpy (spr, "slr");
121+ break;
122 default :
123 if (((((instr & IMM_MASK) >> IMM_LOW) ^ op->immval_mask) & 0xE000)
124 == REG_PVR_MASK)
125diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
126index 867263e..a2a42d0 100644
127--- a/opcodes/microblaze-opcm.h
128+++ b/opcodes/microblaze-opcm.h
129@@ -79,6 +79,8 @@ enum microblaze_instr_type
130 #define REG_BTR_MASK 0x800b
131 #define REG_EDR_MASK 0x800d
132 #define REG_PVR_MASK 0xa000
133+#define REG_SLR_MASK 0x8800
134+#define REG_SHR_MASK 0x8802
135
136 #define REG_PID_MASK 0x9000
137 #define REG_ZPR_MASK 0x9001
138@@ -100,6 +102,8 @@ enum microblaze_instr_type
139 #define REG_FSR 39 /* FPU Status reg. */
140 #define REG_BTR 43 /* Branch Target reg. */
141 #define REG_EDR 45 /* Exception reg. */
142+#define REG_SHR 50 /* Stack High reg. */
143+#define REG_SLR 51 /* Stack Low reg. */
144 #define REG_PVR 40960 /* Program Verification reg. */
145
146 #define REG_PID 36864 /* MMU: Process ID reg. */
147--
1481.7.5.4
149
diff --git a/recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch b/recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch
new file mode 100644
index 00000000..fbd3744f
--- /dev/null
+++ b/recipes-devtools/binutils/files/0010-7de425548753461fd2768017d3be677ba2b2a583.patch
@@ -0,0 +1,83 @@
1From 7de425548753461fd2768017d3be677ba2b2a583 Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Wed, 21 Nov 2012 17:54:09 +0000
4Subject: Add swap byte (swapb) and swap halfword (swaph) opcodes.
5
6binutils/opcodes
7 * microblaze-opc.h (op_code_struct): Add swapb, swaph Increase MAX_OPCODES.
8 * microblaze-opcm.h (microblaze_instr): Likewise
9binutils/gas/testsuite
10 * gas/microblaze/allinsn.s: Add swapb, swaph
11 * gas/microblaze/allinsn.d: Likewise
12
13Upstream-Status: Backport
14
15diff --git a/gas/testsuite/gas/microblaze/allinsn.d b/gas/testsuite/gas/microblaze/allinsn.d
16index 4a03340..b454fdb 100644
17--- a/gas/testsuite/gas/microblaze/allinsn.d
18+++ b/gas/testsuite/gas/microblaze/allinsn.d
19@@ -41,3 +41,9 @@ Disassembly of section .text:
20 30: b0000000 imm 0
21 34: 31600000 addik r11, r0, 0
22 38: 940bc802 mts rshr, r11
23+
24+0000003c <swapb>:
25+ 3c: 900001e0 swapb r0, r0
26+
27+00000040 <swaph>:
28+ 40: 900001e2 swaph r0, r0
29diff --git a/gas/testsuite/gas/microblaze/allinsn.s b/gas/testsuite/gas/microblaze/allinsn.s
30index 437444f..ffe91ca 100644
31--- a/gas/testsuite/gas/microblaze/allinsn.s
32+++ b/gas/testsuite/gas/microblaze/allinsn.s
33@@ -46,4 +46,12 @@ regslr:
34 regshr:
35 la r11,r0,r0
36 mts rshr,r11
37+ .text
38+ .global swapb
39+swapb:
40+ swapb r0,r0
41+ .text
42+ .global swaph
43+swaph:
44+ swaph r0,r0
45
46diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
47index 0447fc5..404985b 100644
48--- a/opcodes/microblaze-opc.h
49+++ b/opcodes/microblaze-opc.h
50@@ -101,7 +101,7 @@
51 #define DELAY_SLOT 1
52 #define NO_DELAY_SLOT 0
53
54-#define MAX_OPCODES 287
55+#define MAX_OPCODES 289
56
57 struct op_code_struct
58 {
59@@ -402,6 +402,8 @@ struct op_code_struct
60 {"clz", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900000E0, OPCODE_MASK_H34, clz, special_inst },
61 {"mbar", INST_TYPE_IMM5, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8020004, OPCODE_MASK_HN, mbar, special_inst },
62 {"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. */
63+ {"swapb", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E0, OPCODE_MASK_H4, swapb, arithmetic_inst },
64+ {"swaph", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x900001E2, OPCODE_MASK_H4, swaph, arithmetic_inst },
65 {"", 0, 0, 0, 0, 0, 0, 0, 0},
66 };
67
68diff --git a/opcodes/microblaze-opcm.h b/opcodes/microblaze-opcm.h
69index a2a42d0..124cdec 100644
70--- a/opcodes/microblaze-opcm.h
71+++ b/opcodes/microblaze-opcm.h
72@@ -27,7 +27,7 @@ enum microblaze_instr
73 {
74 add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, clz, cmp, cmpu,
75 addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
76- mulh, mulhu, mulhsu,
77+ mulh, mulhu, mulhsu,swapb,swaph,
78 idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
79 ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor,
80 andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16,
81--
821.7.5.4
83
diff --git a/recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch b/recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch
new file mode 100644
index 00000000..60205e53
--- /dev/null
+++ b/recipes-devtools/binutils/files/0011-77625f8c77d14a67bc542bb790e6f826c725de4c.patch
@@ -0,0 +1,89 @@
1From 77625f8c77d14a67bc542bb790e6f826c725de4c Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Thu, 29 Nov 2012 21:08:59 +0000
4Subject: opcodes/Changelog: * microblaze-opc.h: Rename
5 INST_TYPE_RD_R1_SPECIAL to INST_TYPE_R1_R2_SPECIAL *
6 microblaze-dis.c (print_insn_microblaze): Same. gas/Changelog *
7 gas/config/tc-microblaze.c: Rename INST_TYPE_RD_R1_SPECIAL to
8 INST_TYPE_R1_R2_SPECIAL, don't set RD for wic.
9
10Upstream-Status: Backport
11
12diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
13index 5a427a0..e9c7846 100644
14--- a/gas/config/tc-microblaze.c
15+++ b/gas/config/tc-microblaze.c
16@@ -1358,16 +1358,16 @@ md_assemble (char * str)
17 output = frag_more (isize);
18 break;
19
20- case INST_TYPE_RD_R1_SPECIAL:
21+ case INST_TYPE_R1_R2_SPECIAL:
22 if (strcmp (op_end, ""))
23- op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
24+ op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
25 else
26 {
27 as_fatal (_("Error in statement syntax"));
28 reg1 = 0;
29 }
30 if (strcmp (op_end, ""))
31- op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
32+ op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
33 else
34 {
35 as_fatal (_("Error in statement syntax"));
36@@ -1381,7 +1381,6 @@ md_assemble (char * str)
37 as_fatal (_("Cannot use special register with this instruction"));
38
39 /* insn wic ra, rb => wic ra, ra, rb. */
40- inst |= (reg1 << RD_LOW) & RD_MASK;
41 inst |= (reg1 << RA_LOW) & RA_MASK;
42 inst |= (reg2 << RB_LOW) & RB_MASK;
43
44diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c
45index 7e3a546..bf028c4 100644
46--- a/opcodes/microblaze-dis.c
47+++ b/opcodes/microblaze-dis.c
48@@ -383,8 +383,8 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
49 case INST_TYPE_R1:
50 print_func (stream, "\t%s", get_field_r1 (inst));
51 break;
52- case INST_TYPE_RD_R1_SPECIAL:
53- print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_r2 (inst));
54+ case INST_TYPE_R1_R2_SPECIAL:
55+ print_func (stream, "\t%s, %s", get_field_r1 (inst), get_field_r2 (inst));
56 break;
57 case INST_TYPE_RD_IMM15:
58 print_func (stream, "\t%s, %s", get_field_rd (inst), get_field_imm15 (inst));
59diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
60index 404985b..e9da12a 100644
61--- a/opcodes/microblaze-opc.h
62+++ b/opcodes/microblaze-opc.h
63@@ -45,7 +45,7 @@
64 #define INST_TYPE_R1_RFSL 15
65
66 /* New insn type for insn cache. */
67-#define INST_TYPE_RD_R1_SPECIAL 16
68+#define INST_TYPE_R1_R2_SPECIAL 16
69
70 /* New insn type for msrclr, msrset insns. */
71 #define INST_TYPE_RD_IMM15 17
72@@ -171,10 +171,10 @@ struct op_code_struct
73 {"srl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000041, OPCODE_MASK_H34, srl, logical_inst },
74 {"sext8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000060, OPCODE_MASK_H34, sext8, logical_inst },
75 {"sext16",INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000061, OPCODE_MASK_H34, sext16, logical_inst },
76- {"wic", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst },
77- {"wdc", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst },
78- {"wdc.clear", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst },
79- {"wdc.flush", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst },
80+ {"wic", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst },
81+ {"wdc", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst },
82+ {"wdc.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst },
83+ {"wdc.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst },
84 {"mts", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst },
85 {"mfs", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst },
86 {"br", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst },
87--
881.7.5.4
89
diff --git a/recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch b/recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch
new file mode 100644
index 00000000..01f5837d
--- /dev/null
+++ b/recipes-devtools/binutils/files/0012-b0ea811a61103f378351c9aa2cb16bd3010b0a31.patch
@@ -0,0 +1,1371 @@
1From b0ea811a61103f378351c9aa2cb16bd3010b0a31 Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Tue, 11 Dec 2012 16:56:50 +0000
4Subject: Microblaze: Add support for handling TLS symbol suffixes and
5 generating TLS relocs for General Dynamic and Local Dynamic models.
6
7bfd/Changelog
8 * reloc.c: Add new relocations
9 * bfd-in2.h: Regenerated
10 * libbfd.h: Regenerated
11 * elf32-microblaze.c (microblaze_elf_howto_raw):
12 Add TLS relocations
13 (microblaze_elf_reloc_type_lookup): Likewise
14 (elf32_mb_link_hash_entry): define TLS reference types
15 (elf32_mb_link_hash_table): add TLS Local dynamic GOT entry
16 #define has_tls_reloc if section has TLS relocs
17 (dtprel_base), (check_unique_offset): New
18 (microblaze_elf_output_dynamic_relocation): output simple
19 dynamic relocation into SRELOC.
20 (microblaze_elf_relocate_section): Accommodate TLS relocations.
21 (microblaze_elf_check_relocs): Likewise
22 (update_local_sym_info): New
23 (microblaze_elf_copy_indirect_symbol): Add tls_mask.
24 (allocate_dynrelocs): Handle TLS symbol
25 (microblaze_elf_size_dynamic_sections): Set size and offset
26 (microblaze_elf_finish_dynamic_symbol): Use
27 microblaze_elf_output_dynamic_relocation
28
29gas/Changelog
30 * config/tc-microblaze.c: Define TLS offsets
31 (md_relax_table): Add TLS offsets
32 (imm_types), (match_imm), (get_imm_otype): New to support
33 TLS offsets.
34 (tc_microblaze_fix_adjustable): Add TLS relocs.
35 (md_convert_frag): Support TLS offsets.
36 (md_apply_fix), (md_estimate_size_before_relax), (tc_gen_reloc):
37 Add TLS relocs
38
39include/Changelog
40 * elf/microblaze.h: Add TLS relocs to START_RELOC_NUMBERS
41
42Upstream-Status: Backport
43
44diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
45index bba8757..82537c1 100644
46--- a/bfd/bfd-in2.h
47+++ b/bfd/bfd-in2.h
48@@ -5071,6 +5071,37 @@ value in a word. The relocation is relative offset from */
49 the dynamic object into the runtime process image. */
50 BFD_RELOC_MICROBLAZE_COPY,
51
52+/* Unused Reloc */
53+ BFD_RELOC_MICROBLAZE_64_TLS,
54+
55+/* This is a 64 bit reloc that stores the 32 bit GOT relative value
56+of the GOT TLS GD info entry in two words (with an imm instruction). The
57+relocation is GOT offset. */
58+ BFD_RELOC_MICROBLAZE_64_TLSGD,
59+
60+/* This is a 64 bit reloc that stores the 32 bit GOT relative value
61+of the GOT TLS LD info entry in two words (with an imm instruction). The
62+relocation is GOT offset. */
63+ BFD_RELOC_MICROBLAZE_64_TLSLD,
64+
65+/* This is a 32 bit reloc that stores the Module ID to GOT(n). */
66+ BFD_RELOC_MICROBLAZE_32_TLSDTPMOD,
67+
68+/* This is a 32 bit reloc that stores TLS offset to GOT(n+1). */
69+ BFD_RELOC_MICROBLAZE_32_TLSDTPREL,
70+
71+/* This is a 32 bit reloc for storing TLS offset to two words (uses imm
72+instruction) */
73+ BFD_RELOC_MICROBLAZE_64_TLSDTPREL,
74+
75+/* This is a 64 bit reloc that stores 32-bit thread pointer relative offset
76+to two words (uses imm instruction). */
77+ BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL,
78+
79+/* This is a 64 bit reloc that stores 32-bit thread pointer relative offset
80+to two words (uses imm instruction). */
81+ BFD_RELOC_MICROBLAZE_64_TLSTPREL,
82+
83 /* AArch64 ADD immediate instruction, holding bits 0 to 11 of the address.
84 Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
85 BFD_RELOC_AARCH64_ADD_LO12,
86diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
87index be2de13..9d0a7ca 100644
88--- a/bfd/elf32-microblaze.c
89+++ b/bfd/elf32-microblaze.c
90@@ -370,6 +370,132 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
91 0, /* Source Mask. */
92 0x0000ffff, /* Dest Mask. */
93 FALSE), /* PC relative offset? */
94+
95+ /* Marker relocs for TLS. */
96+ HOWTO (R_MICROBLAZE_TLS,
97+ 0, /* rightshift */
98+ 2, /* size (0 = byte, 1 = short, 2 = long) */
99+ 32, /* bitsize */
100+ FALSE, /* pc_relative */
101+ 0, /* bitpos */
102+ complain_overflow_dont, /* complain_on_overflow */
103+ bfd_elf_generic_reloc, /* special_function */
104+ "R_MICROBLAZE_TLS", /* name */
105+ FALSE, /* partial_inplace */
106+ 0, /* src_mask */
107+ 0x0000ffff, /* dst_mask */
108+ FALSE), /* pcrel_offset */
109+
110+ HOWTO (R_MICROBLAZE_TLSGD,
111+ 0, /* rightshift */
112+ 2, /* size (0 = byte, 1 = short, 2 = long) */
113+ 32, /* bitsize */
114+ FALSE, /* pc_relative */
115+ 0, /* bitpos */
116+ complain_overflow_dont, /* complain_on_overflow */
117+ bfd_elf_generic_reloc, /* special_function */
118+ "R_MICROBLAZE_TLSGD", /* name */
119+ FALSE, /* partial_inplace */
120+ 0, /* src_mask */
121+ 0x0000ffff, /* dst_mask */
122+ FALSE), /* pcrel_offset */
123+
124+ HOWTO (R_MICROBLAZE_TLSLD,
125+ 0, /* rightshift */
126+ 2, /* size (0 = byte, 1 = short, 2 = long) */
127+ 32, /* bitsize */
128+ FALSE, /* pc_relative */
129+ 0, /* bitpos */
130+ complain_overflow_dont, /* complain_on_overflow */
131+ bfd_elf_generic_reloc, /* special_function */
132+ "R_MICROBLAZE_TLSLD", /* name */
133+ FALSE, /* partial_inplace */
134+ 0, /* src_mask */
135+ 0x0000ffff, /* dst_mask */
136+ FALSE), /* pcrel_offset */
137+
138+ /* Computes the load module index of the load module that contains the
139+ definition of its TLS sym. */
140+ HOWTO (R_MICROBLAZE_TLSDTPMOD32,
141+ 0, /* rightshift */
142+ 2, /* size (0 = byte, 1 = short, 2 = long) */
143+ 32, /* bitsize */
144+ FALSE, /* pc_relative */
145+ 0, /* bitpos */
146+ complain_overflow_dont, /* complain_on_overflow */
147+ bfd_elf_generic_reloc, /* special_function */
148+ "R_MICROBLAZE_TLSDTPMOD32", /* name */
149+ FALSE, /* partial_inplace */
150+ 0, /* src_mask */
151+ 0x0000ffff, /* dst_mask */
152+ FALSE), /* pcrel_offset */
153+
154+ /* Computes a dtv-relative displacement, the difference between the value
155+ of sym+add and the base address of the thread-local storage block that
156+ contains the definition of sym, minus 0x8000. Used for initializing GOT */
157+ HOWTO (R_MICROBLAZE_TLSDTPREL32,
158+ 0, /* rightshift */
159+ 2, /* size (0 = byte, 1 = short, 2 = long) */
160+ 32, /* bitsize */
161+ FALSE, /* pc_relative */
162+ 0, /* bitpos */
163+ complain_overflow_dont, /* complain_on_overflow */
164+ bfd_elf_generic_reloc, /* special_function */
165+ "R_MICROBLAZE_TLSDTPREL32", /* name */
166+ FALSE, /* partial_inplace */
167+ 0, /* src_mask */
168+ 0x0000ffff, /* dst_mask */
169+ FALSE), /* pcrel_offset */
170+
171+ /* Computes a dtv-relative displacement, the difference between the value
172+ of sym+add and the base address of the thread-local storage block that
173+ contains the definition of sym, minus 0x8000. */
174+ HOWTO (R_MICROBLAZE_TLSDTPREL64,
175+ 0, /* rightshift */
176+ 2, /* size (0 = byte, 1 = short, 2 = long) */
177+ 32, /* bitsize */
178+ FALSE, /* pc_relative */
179+ 0, /* bitpos */
180+ complain_overflow_dont, /* complain_on_overflow */
181+ bfd_elf_generic_reloc, /* special_function */
182+ "R_MICROBLAZE_TLSDTPREL64", /* name */
183+ FALSE, /* partial_inplace */
184+ 0, /* src_mask */
185+ 0x0000ffff, /* dst_mask */
186+ FALSE), /* pcrel_offset */
187+
188+ /* Computes a tp-relative displacement, the difference between the value of
189+ sym+add and the value of the thread pointer (r13). */
190+ HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
191+ 0, /* rightshift */
192+ 2, /* size (0 = byte, 1 = short, 2 = long) */
193+ 32, /* bitsize */
194+ FALSE, /* pc_relative */
195+ 0, /* bitpos */
196+ complain_overflow_dont, /* complain_on_overflow */
197+ bfd_elf_generic_reloc, /* special_function */
198+ "R_MICROBLAZE_TLSGOTTPREL32", /* name */
199+ FALSE, /* partial_inplace */
200+ 0, /* src_mask */
201+ 0x0000ffff, /* dst_mask */
202+ FALSE), /* pcrel_offset */
203+
204+ /* Computes a tp-relative displacement, the difference between the value of
205+ sym+add and the value of the thread pointer (r13). */
206+ HOWTO (R_MICROBLAZE_TLSTPREL32,
207+ 0, /* rightshift */
208+ 2, /* size (0 = byte, 1 = short, 2 = long) */
209+ 32, /* bitsize */
210+ FALSE, /* pc_relative */
211+ 0, /* bitpos */
212+ complain_overflow_dont, /* complain_on_overflow */
213+ bfd_elf_generic_reloc, /* special_function */
214+ "R_MICROBLAZE_TLSTPREL32", /* name */
215+ FALSE, /* partial_inplace */
216+ 0, /* src_mask */
217+ 0x0000ffff, /* dst_mask */
218+ FALSE), /* pcrel_offset */
219+
220 };
221
222 #ifndef NUM_ELEM
223@@ -461,6 +587,27 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
224 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
225 microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
226 break;
227+ case BFD_RELOC_MICROBLAZE_64_TLSGD:
228+ microblaze_reloc = R_MICROBLAZE_TLSGD;
229+ break;
230+ case BFD_RELOC_MICROBLAZE_64_TLSLD:
231+ microblaze_reloc = R_MICROBLAZE_TLSLD;
232+ break;
233+ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
234+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
235+ break;
236+ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
237+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
238+ break;
239+ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
240+ microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
241+ break;
242+ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
243+ microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
244+ break;
245+ case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
246+ microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
247+ break;
248 case BFD_RELOC_MICROBLAZE_COPY:
249 microblaze_reloc = R_MICROBLAZE_COPY;
250 break;
251@@ -550,8 +697,21 @@ struct elf32_mb_link_hash_entry
252 /* Track dynamic relocs copied for this symbol. */
253 struct elf32_mb_dyn_relocs *dyn_relocs;
254
255+ /* TLS Reference Types for the symbol; Updated by check_relocs */
256+#define TLS_GD 1 /* GD reloc. */
257+#define TLS_LD 2 /* LD reloc. */
258+#define TLS_TPREL 4 /* TPREL reloc, => IE. */
259+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
260+#define TLS_TLS 16 /* Any TLS reloc. */
261+ unsigned char tls_mask;
262+
263 };
264
265+#define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
266+#define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
267+#define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
268+#define IS_TLS_NONE(x) (x == 0)
269+
270 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
271
272 /* ELF linker hash table. */
273@@ -571,8 +731,17 @@ struct elf32_mb_link_hash_table
274
275 /* Small local sym to section mapping cache. */
276 struct sym_cache sym_sec;
277+
278+ /* TLS Local Dynamic GOT Entry */
279+ union {
280+ bfd_signed_vma refcount;
281+ bfd_vma offset;
282+ } tlsld_got;
283 };
284
285+/* Nonzero if this section has TLS related relocations. */
286+#define has_tls_reloc sec_flg0
287+
288 /* Get the ELF linker hash table from a link_info structure. */
289
290 #define elf32_mb_hash_table(p) \
291@@ -604,6 +773,7 @@ link_hash_newfunc (struct bfd_hash_entry *entry,
292
293 eh = (struct elf32_mb_link_hash_entry *) entry;
294 eh->dyn_relocs = NULL;
295+ eh->tls_mask = 0;
296 }
297
298 return entry;
299@@ -654,6 +824,40 @@ microblaze_elf_final_sdp (struct bfd_link_info *info)
300 + h->u.def.section->output_offset);
301 }
302
303+static bfd_vma
304+dtprel_base (struct bfd_link_info *info)
305+{
306+ /* If tls_sec is NULL, we should have signalled an error already. */
307+ if (elf_hash_table (info)->tls_sec == NULL)
308+ return 0;
309+ return elf_hash_table (info)->tls_sec->vma;
310+}
311+
312+/* The size of the thread control block. */
313+#define TCB_SIZE 8
314+
315+/* Output a simple dynamic relocation into SRELOC. */
316+
317+static void
318+microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
319+ asection *sreloc,
320+ unsigned long reloc_index,
321+ unsigned long indx,
322+ int r_type,
323+ bfd_vma offset,
324+ bfd_vma addend)
325+{
326+
327+ Elf_Internal_Rela rel;
328+
329+ rel.r_info = ELF32_R_INFO (indx, r_type);
330+ rel.r_offset = offset;
331+ rel.r_addend = addend;
332+
333+ bfd_elf32_swap_reloca_out (output_bfd, &rel,
334+ (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
335+}
336+
337 /* This code is taken from elf32-m32r.c
338 There is some attempt to make this function usable for many architectures,
339 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
340@@ -707,6 +911,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
341 bfd_boolean ret = TRUE;
342 asection *sreloc;
343 bfd_vma *local_got_offsets;
344+ unsigned int tls_type;
345
346 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
347 microblaze_elf_howto_init ();
348@@ -738,6 +943,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
349
350 h = NULL;
351 r_type = ELF32_R_TYPE (rel->r_info);
352+ tls_type = 0;
353+
354 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
355 {
356 (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
357@@ -971,70 +1178,182 @@ microblaze_elf_relocate_section (bfd *output_bfd,
358 break;
359 }
360
361+ case (int) R_MICROBLAZE_TLSGD:
362+ tls_type = (TLS_TLS | TLS_GD);
363+ goto dogot;
364+ case (int) R_MICROBLAZE_TLSLD:
365+ tls_type = (TLS_TLS | TLS_LD);
366+ dogot:
367 case (int) R_MICROBLAZE_GOT_64:
368 {
369+ bfd_vma *offp;
370+ bfd_vma off, off2;
371+ unsigned long indx;
372+ bfd_vma static_value;
373+
374+ bfd_boolean need_relocs = FALSE;
375 if (htab->sgot == NULL)
376 abort ();
377- if (h == NULL)
378+
379+ indx = 0;
380+ offp = NULL;
381+
382+ /* 1. Identify GOT Offset;
383+ 2. Compute Static Values
384+ 3. Process Module Id, Process Offset
385+ 4. Fixup Relocation with GOT offset value. */
386+
387+ /* 1. Determine GOT Offset to use : TLS_LD, global, local */
388+ if (IS_TLS_LD (tls_type))
389+ offp = &htab->tlsld_got.offset;
390+ else if (h != NULL)
391+ {
392+ if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1)
393+ offp = &h->got.offset;
394+ else
395+ abort ();
396+ }
397+ else
398 {
399- bfd_vma off;
400 if (local_got_offsets == NULL)
401 abort ();
402- off = local_got_offsets[r_symndx];
403- /* The LSB indicates whether we've already
404- created relocation. */
405- if (off & 1)
406- off &= ~1;
407- else
408- {
409- bfd_put_32 (output_bfd, relocation + addend,
410- htab->sgot->contents + off);
411+ offp = &local_got_offsets[r_symndx];
412+ }
413+
414+ if (!offp)
415+ abort ();
416+
417+ off = (*offp) & ~1;
418+ off2 = off;
419+
420+ if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
421+ off2 = off + 4;
422+
423+ /* Symbol index to use for relocs */
424+ if (h != NULL)
425+ {
426+ bfd_boolean dyn =
427+ elf_hash_table (info)->dynamic_sections_created;
428+
429+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
430+ && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h)))
431+ indx = h->dynindx;
432+ }
433
434- if (info->shared)
435+ /* Need to generate relocs ? */
436+ if ((info->shared || indx != 0)
437+ && (h == NULL
438+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
439+ || h->root.type != bfd_link_hash_undefweak))
440+ need_relocs = TRUE;
441+
442+ /* 2. Compute/Emit Static value of r-expression */
443+ static_value = relocation + addend;
444+
445+ /* 3. Process module-id and offset */
446+ if (! ((*offp) & 1) )
447+ {
448+ bfd_vma got_offset;
449+
450+ got_offset = (htab->sgot->output_section->vma
451+ + htab->sgot->output_offset
452+ + off);
453+
454+ /* Process module-id */
455+ if (IS_TLS_LD(tls_type))
456+ {
457+ if (! info->shared)
458 {
459- Elf_Internal_Rela outrel;
460- bfd_byte *loc;
461- if (htab->srelgot == NULL)
462- abort ();
463- outrel.r_offset = (htab->sgot->output_section->vma
464- + htab->sgot->output_offset
465- + off);
466- outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
467- outrel.r_addend = relocation + addend;
468- loc = htab->srelgot->contents;
469- loc += htab->srelgot->reloc_count++
470- * sizeof (Elf32_External_Rela);
471- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
472+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
473+ }
474+ else
475+ {
476+ microblaze_elf_output_dynamic_relocation (output_bfd,
477+ htab->srelgot, htab->srelgot->reloc_count++,
478+ /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
479+ got_offset, 0);
480 }
481- local_got_offsets[r_symndx] |= 1;
482 }
483- relocation = htab->sgot->output_section->vma
484- + htab->sgot->output_offset + off
485- - htab->sgotplt->output_section->vma
486- - htab->sgotplt->output_offset;
487- unresolved_reloc = FALSE;
488- }
489- else
490- {
491- if (htab->sgotplt != NULL && h != NULL
492- && h->got.offset != (bfd_vma) -1)
493+ else if (IS_TLS_GD(tls_type))
494+ {
495+ if (! need_relocs)
496+ {
497+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
498+ }
499+ else
500+ {
501+ microblaze_elf_output_dynamic_relocation (output_bfd,
502+ htab->srelgot,
503+ htab->srelgot->reloc_count++,
504+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
505+ got_offset, indx ? 0 : static_value);
506+ }
507+ }
508+
509+ /* Process Offset */
510+ if (htab->srelgot == NULL)
511+ abort ();
512+
513+ got_offset = (htab->sgot->output_section->vma
514+ + htab->sgot->output_offset
515+ + off2);
516+ if (IS_TLS_LD(tls_type))
517+ {
518+ /* For LD, offset should be 0 */
519+ *offp |= 1;
520+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2);
521+ }
522+ else if (IS_TLS_GD(tls_type))
523 {
524- bfd_put_32 (output_bfd, relocation + addend,
525- htab->sgot->contents + h->got.offset);
526- relocation = htab->sgot->output_section->vma
527- + htab->sgot->output_offset
528- + h->got.offset
529- - htab->sgotplt->output_section->vma
530- - htab->sgotplt->output_offset;
531- unresolved_reloc = FALSE;
532+ *offp |= 1;
533+ static_value -= dtprel_base(info);
534+ if (need_relocs)
535+ {
536+ microblaze_elf_output_dynamic_relocation (output_bfd,
537+ htab->srelgot, htab->srelgot->reloc_count++,
538+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
539+ got_offset, indx ? 0 : static_value);
540+ }
541+ else
542+ {
543+ bfd_put_32 (output_bfd, static_value,
544+ htab->sgot->contents + off2);
545+ }
546 }
547 else
548- abort (); /* ??? */
549+ {
550+ bfd_put_32 (output_bfd, static_value,
551+ htab->sgot->contents + off2);
552+
553+ /* Relocs for dyn symbols generated by
554+ finish_dynamic_symbols */
555+ if (info->shared && h == NULL)
556+ {
557+ *offp |= 1;
558+ microblaze_elf_output_dynamic_relocation (output_bfd,
559+ htab->srelgot, htab->srelgot->reloc_count++,
560+ /* symindex= */ indx, R_MICROBLAZE_REL,
561+ got_offset, static_value);
562+ }
563+ }
564 }
565+
566+ /* 4. Fixup Relocation with GOT offset value
567+ Compute relative address of GOT entry for applying
568+ the current relocation */
569+ relocation = htab->sgot->output_section->vma
570+ + htab->sgot->output_offset
571+ + off
572+ - htab->sgotplt->output_section->vma
573+ - htab->sgotplt->output_offset;
574+
575+ /* Apply Current Relocation */
576 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
577 contents + offset + endian);
578 bfd_put_16 (input_bfd, relocation & 0xffff,
579 contents + offset + endian + INST_WORD_SIZE);
580+
581+ unresolved_reloc = FALSE;
582 break;
583 }
584
585@@ -1064,6 +1383,14 @@ microblaze_elf_relocate_section (bfd *output_bfd,
586 break;
587 }
588
589+ case (int) R_MICROBLAZE_TLSDTPREL64:
590+ relocation += addend;
591+ relocation -= dtprel_base(info);
592+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
593+ contents + offset + 2);
594+ bfd_put_16 (input_bfd, relocation & 0xffff,
595+ contents + offset + 2 + INST_WORD_SIZE);
596+ break;
597 case (int) R_MICROBLAZE_64_PCREL :
598 case (int) R_MICROBLAZE_64:
599 case (int) R_MICROBLAZE_32:
600@@ -1941,6 +2268,33 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
601 return TRUE;
602 }
603
604+static bfd_boolean
605+update_local_sym_info (bfd *abfd,
606+ Elf_Internal_Shdr *symtab_hdr,
607+ unsigned long r_symndx,
608+ unsigned int tls_type)
609+{
610+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
611+ unsigned char *local_got_tls_masks;
612+
613+ if (local_got_refcounts == NULL)
614+ {
615+ bfd_size_type size = symtab_hdr->sh_info;
616+
617+ size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
618+ local_got_refcounts = bfd_zalloc (abfd, size);
619+ if (local_got_refcounts == NULL)
620+ return FALSE;
621+ elf_local_got_refcounts (abfd) = local_got_refcounts;
622+ }
623+
624+ local_got_tls_masks =
625+ (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
626+ local_got_tls_masks[r_symndx] |= tls_type;
627+ local_got_refcounts[r_symndx] += 1;
628+
629+ return TRUE;
630+}
631 /* Look through the relocs for a section during the first phase. */
632
633 static bfd_boolean
634@@ -1977,6 +2331,7 @@ microblaze_elf_check_relocs (bfd * abfd,
635 unsigned int r_type;
636 struct elf_link_hash_entry * h;
637 unsigned long r_symndx;
638+ unsigned char tls_type = 0;
639
640 r_symndx = ELF32_R_SYM (rel->r_info);
641 r_type = ELF32_R_TYPE (rel->r_info);
642@@ -2012,6 +2367,13 @@ microblaze_elf_check_relocs (bfd * abfd,
643 break;
644
645 /* This relocation requires .got entry. */
646+ case R_MICROBLAZE_TLSGD:
647+ tls_type |= (TLS_TLS | TLS_GD);
648+ goto dogottls;
649+ case R_MICROBLAZE_TLSLD:
650+ tls_type |= (TLS_TLS | TLS_LD);
651+ dogottls:
652+ sec->has_tls_reloc = 1;
653 case R_MICROBLAZE_GOT_64:
654 if (htab->sgot == NULL)
655 {
656@@ -2023,25 +2385,12 @@ microblaze_elf_check_relocs (bfd * abfd,
657 if (h != NULL)
658 {
659 h->got.refcount += 1;
660+ elf32_mb_hash_entry (h)->tls_mask |= tls_type;
661 }
662 else
663 {
664- bfd_signed_vma *local_got_refcounts;
665-
666- /* This is a global offset table entry for a local symbol. */
667- local_got_refcounts = elf_local_got_refcounts (abfd);
668- if (local_got_refcounts == NULL)
669- {
670- bfd_size_type size;
671-
672- size = symtab_hdr->sh_info;
673- size *= sizeof (bfd_signed_vma);
674- local_got_refcounts = bfd_zalloc (abfd, size);
675- if (local_got_refcounts == NULL)
676- return FALSE;
677- elf_local_got_refcounts (abfd) = local_got_refcounts;
678- }
679- local_got_refcounts[r_symndx] += 1;
680+ if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
681+ return FALSE;
682 }
683 break;
684
685@@ -2105,45 +2454,16 @@ microblaze_elf_check_relocs (bfd * abfd,
686
687 if (sreloc == NULL)
688 {
689- const char *name;
690 bfd *dynobj;
691- unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
692- unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
693-
694- name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
695- if (name == NULL)
696- return FALSE;
697-
698- if (strncmp (name, ".rela", 5) != 0
699- || strcmp (bfd_get_section_name (abfd, sec),
700- name + 5) != 0)
701- {
702- (*_bfd_error_handler)
703- (_("%B: bad relocation section name `%s\'"),
704- abfd, name);
705- }
706
707 if (htab->elf.dynobj == NULL)
708 htab->elf.dynobj = abfd;
709 dynobj = htab->elf.dynobj;
710
711- sreloc = bfd_get_linker_section (dynobj, name);
712+ sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
713+ 2, abfd, 1);
714 if (sreloc == NULL)
715- {
716- flagword flags;
717-
718- flags = (SEC_HAS_CONTENTS | SEC_READONLY
719- | SEC_IN_MEMORY | SEC_LINKER_CREATED);
720- if ((sec->flags & SEC_ALLOC) != 0)
721- flags |= SEC_ALLOC | SEC_LOAD;
722- sreloc = bfd_make_section_anyway_with_flags (dynobj,
723- name,
724- flags);
725- if (sreloc == NULL
726- || ! bfd_set_section_alignment (dynobj, sreloc, 2))
727- return FALSE;
728- }
729- elf_section_data (sec)->sreloc = sreloc;
730+ return FALSE;
731 }
732
733 /* If this is a global symbol, we count the number of
734@@ -2274,6 +2594,8 @@ microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
735 eind->dyn_relocs = NULL;
736 }
737
738+ edir->tls_mask |= eind->tls_mask;
739+
740 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
741 }
742
743@@ -2492,8 +2814,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
744 h->needs_plt = 0;
745 }
746
747+ eh = (struct elf32_mb_link_hash_entry *) h;
748 if (h->got.refcount > 0)
749 {
750+ unsigned int need;
751 asection *s;
752
753 /* Make sure this symbol is output as a dynamic symbol.
754@@ -2505,15 +2829,43 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
755 return FALSE;
756 }
757
758- s = htab->sgot;
759- h->got.offset = s->size;
760- s->size += 4;
761- htab->srelgot->size += sizeof (Elf32_External_Rela);
762+ need = 0;
763+ if ((eh->tls_mask & TLS_TLS) != 0)
764+ {
765+ /* Handle TLS Symbol */
766+ if ((eh->tls_mask & TLS_LD) != 0)
767+ {
768+ if (!eh->elf.def_dynamic)
769+ /* We'll just use htab->tlsld_got.offset. This should
770+ always be the case. It's a little odd if we have
771+ a local dynamic reloc against a non-local symbol. */
772+ htab->tlsld_got.refcount += 1;
773+ else
774+ need += 8;
775+ }
776+ if ((eh->tls_mask & TLS_GD) != 0)
777+ need += 8;
778+ }
779+ else
780+ {
781+ /* Regular (non-TLS) symbol */
782+ need += 4;
783+ }
784+ if (need == 0)
785+ {
786+ h->got.offset = (bfd_vma) -1;
787+ }
788+ else
789+ {
790+ s = htab->sgot;
791+ h->got.offset = s->size;
792+ s->size += need;
793+ htab->srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
794+ }
795 }
796 else
797 h->got.offset = (bfd_vma) -1;
798
799- eh = (struct elf32_mb_link_hash_entry *) h;
800 if (eh->dyn_relocs == NULL)
801 return TRUE;
802
803@@ -2611,6 +2963,7 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
804 bfd_signed_vma *end_local_got;
805 bfd_size_type locsymcount;
806 Elf_Internal_Shdr *symtab_hdr;
807+ unsigned char *lgot_masks;
808 asection *srel;
809
810 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
811@@ -2650,17 +3003,36 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
812 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
813 locsymcount = symtab_hdr->sh_info;
814 end_local_got = local_got + locsymcount;
815+ lgot_masks = (unsigned char *) end_local_got;
816 s = htab->sgot;
817 srel = htab->srelgot;
818
819- for (; local_got < end_local_got; ++local_got)
820- {
821- if (*local_got > 0)
822- {
823- *local_got = s->size;
824- s->size += 4;
825- if (info->shared)
826- srel->size += sizeof (Elf32_External_Rela);
827+ for (; local_got < end_local_got; ++local_got, ++lgot_masks)
828+ {
829+ if (*local_got > 0)
830+ {
831+ unsigned int need = 0;
832+ if ((*lgot_masks & TLS_TLS) != 0)
833+ {
834+ if ((*lgot_masks & TLS_GD) != 0)
835+ need += 8;
836+ if ((*lgot_masks & TLS_LD) != 0)
837+ htab->tlsld_got.refcount += 1;
838+ }
839+ else
840+ need += 4;
841+
842+ if (need == 0)
843+ {
844+ *local_got = (bfd_vma) -1;
845+ }
846+ else
847+ {
848+ *local_got = s->size;
849+ s->size += need;
850+ if (info->shared)
851+ srel->size += need * (sizeof (Elf32_External_Rela) / 4);
852+ }
853 }
854 else
855 *local_got = (bfd_vma) -1;
856@@ -2671,6 +3043,16 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
857 sym dynamic relocs. */
858 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
859
860+ if (htab->tlsld_got.refcount > 0)
861+ {
862+ htab->tlsld_got.offset = htab->sgot->size;
863+ htab->sgot->size += 8;
864+ if (info->shared)
865+ htab->srelgot->size += sizeof (Elf32_External_Rela);
866+ }
867+ else
868+ htab->tlsld_got.offset = (bfd_vma) -1;
869+
870 if (elf_hash_table (info)->dynamic_sections_created)
871 {
872 /* Make space for the trailing nop in .plt. */
873@@ -2789,6 +3171,7 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
874 Elf_Internal_Sym *sym)
875 {
876 struct elf32_mb_link_hash_table *htab;
877+ struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
878
879 htab = elf32_mb_hash_table (info);
880 if (htab == NULL)
881@@ -2860,12 +3243,14 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
882 }
883 }
884
885- if (h->got.offset != (bfd_vma) -1)
886+ /* h->got.refcount to be checked ? */
887+ if (h->got.offset != (bfd_vma) -1 &&
888+ ! ((h->got.offset & 1) ||
889+ IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
890 {
891 asection *sgot;
892 asection *srela;
893- Elf_Internal_Rela rela;
894- bfd_byte *loc;
895+ bfd_vma offset;
896
897 /* This symbol has an entry in the global offset table. Set it
898 up. */
899@@ -2874,8 +3259,7 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
900 srela = htab->srelgot;
901 BFD_ASSERT (sgot != NULL && srela != NULL);
902
903- rela.r_offset = (sgot->output_section->vma
904- + sgot->output_offset
905+ offset = (sgot->output_section->vma + sgot->output_offset
906 + (h->got.offset &~ (bfd_vma) 1));
907
908 /* If this is a -Bsymbolic link, and the symbol is defined
909@@ -2888,22 +3272,25 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
910 && h->def_regular)
911 {
912 asection *sec = h->root.u.def.section;
913- rela.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
914- rela.r_addend = (h->root.u.def.value
915- + sec->output_section->vma
916- + sec->output_offset);
917+ microblaze_elf_output_dynamic_relocation (output_bfd,
918+ srela, srela->reloc_count++,
919+ /* symindex= */ 0,
920+ R_MICROBLAZE_REL, offset,
921+ h->root.u.def.value
922+ + sec->output_section->vma
923+ + sec->output_offset);
924 }
925 else
926 {
927- rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_GLOB_DAT);
928- rela.r_addend = 0;
929+ microblaze_elf_output_dynamic_relocation (output_bfd,
930+ srela, srela->reloc_count++,
931+ h->dynindx,
932+ R_MICROBLAZE_GLOB_DAT,
933+ offset, 0);
934 }
935
936 bfd_put_32 (output_bfd, (bfd_vma) 0,
937 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
938- loc = srela->contents;
939- loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
940- bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
941 }
942
943 if (h->needs_copy)
944@@ -3073,7 +3460,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
945 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
946 #define ELF_MACHINE_CODE EM_MICROBLAZE
947 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
948-#define ELF_MAXPAGESIZE 0x4 /* 4k, if we ever have 'em. */
949+#define ELF_MAXPAGESIZE 0x1000
950 #define elf_info_to_howto microblaze_elf_info_to_howto
951 #define elf_info_to_howto_rel NULL
952
953diff --git a/bfd/libbfd.h b/bfd/libbfd.h
954index 0458e39..362e35f 100644
955--- a/bfd/libbfd.h
956+++ b/bfd/libbfd.h
957@@ -2420,6 +2420,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
958 "BFD_RELOC_MICROBLAZE_64_GOTOFF",
959 "BFD_RELOC_MICROBLAZE_32_GOTOFF",
960 "BFD_RELOC_MICROBLAZE_COPY",
961+ "BFD_RELOC_MICROBLAZE_64_TLS",
962+ "BFD_RELOC_MICROBLAZE_64_TLSGD",
963+ "BFD_RELOC_MICROBLAZE_64_TLSLD",
964+ "BFD_RELOC_MICROBLAZE_32_TLSDTPMOD",
965+ "BFD_RELOC_MICROBLAZE_32_TLSDTPREL",
966+ "BFD_RELOC_MICROBLAZE_64_TLSDTPREL",
967+ "BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL",
968+ "BFD_RELOC_MICROBLAZE_64_TLSTPREL",
969 "BFD_RELOC_AARCH64_ADD_LO12",
970 "BFD_RELOC_AARCH64_GOT_LD_PREL19",
971 "BFD_RELOC_AARCH64_ADR_GOT_PAGE",
972diff --git a/bfd/reloc.c b/bfd/reloc.c
973index e097887..3f88049 100644
974--- a/bfd/reloc.c
975+++ b/bfd/reloc.c
976@@ -5882,6 +5882,45 @@ ENUM
977 ENUMDOC
978 This is used to tell the dynamic linker to copy the value out of
979 the dynamic object into the runtime process image.
980+ENUM
981+ BFD_RELOC_MICROBLAZE_64_TLS
982+ENUMDOC
983+ Unused Reloc
984+ENUM
985+ BFD_RELOC_MICROBLAZE_64_TLSGD
986+ENUMDOC
987+ This is a 64 bit reloc that stores the 32 bit GOT relative value
988+ of the GOT TLS GD info entry in two words (with an imm instruction). The
989+ relocation is GOT offset.
990+ENUM
991+ BFD_RELOC_MICROBLAZE_64_TLSLD
992+ENUMDOC
993+ This is a 64 bit reloc that stores the 32 bit GOT relative value
994+ of the GOT TLS LD info entry in two words (with an imm instruction). The
995+ relocation is GOT offset.
996+ENUM
997+ BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
998+ENUMDOC
999+ This is a 32 bit reloc that stores the Module ID to GOT(n).
1000+ENUM
1001+ BFD_RELOC_MICROBLAZE_32_TLSDTPREL
1002+ENUMDOC
1003+ This is a 32 bit reloc that stores TLS offset to GOT(n+1).
1004+ENUM
1005+ BFD_RELOC_MICROBLAZE_64_TLSDTPREL
1006+ENUMDOC
1007+ This is a 32 bit reloc for storing TLS offset to two words (uses imm
1008+ instruction)
1009+ENUM
1010+ BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
1011+ENUMDOC
1012+ This is a 64 bit reloc that stores 32-bit thread pointer relative offset
1013+ to two words (uses imm instruction).
1014+ENUM
1015+ BFD_RELOC_MICROBLAZE_64_TLSTPREL
1016+ENUMDOC
1017+ This is a 64 bit reloc that stores 32-bit thread pointer relative offset
1018+ to two words (uses imm instruction).
1019
1020 ENUM
1021 BFD_RELOC_AARCH64_ADD_LO12
1022diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
1023index e9c7846..872737b 100644
1024--- a/gas/config/tc-microblaze.c
1025+++ b/gas/config/tc-microblaze.c
1026@@ -81,7 +81,12 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
1027 #define GOT_OFFSET 8
1028 #define PLT_OFFSET 9
1029 #define GOTOFF_OFFSET 10
1030-
1031+#define TLSGD_OFFSET 11
1032+#define TLSLD_OFFSET 12
1033+#define TLSDTPMOD_OFFSET 13
1034+#define TLSDTPREL_OFFSET 14
1035+#define TLSGOTTPREL_OFFSET 15
1036+#define TLSTPREL_OFFSET 16
1037
1038 /* Initialize the relax table. */
1039 const relax_typeS md_relax_table[] =
1040@@ -97,6 +102,12 @@ const relax_typeS md_relax_table[] =
1041 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */
1042 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */
1043 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */
1044+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 11: TLSGD_OFFSET. */
1045+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 12: TLSLD_OFFSET. */
1046+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
1047+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
1048+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
1049+ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
1050 };
1051
1052 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
1053@@ -599,9 +610,75 @@ parse_exp (char *s, expressionS *e)
1054 }
1055
1056 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
1057+#define IMM_NONE 0
1058 #define IMM_GOT 1
1059 #define IMM_PLT 2
1060 #define IMM_GOTOFF 3
1061+#define IMM_TLSGD 4
1062+#define IMM_TLSLD 5
1063+#define IMM_TLSDTPMOD 6
1064+#define IMM_TLSDTPREL 7
1065+#define IMM_TLSTPREL 8
1066+#define IMM_MAX 9
1067+
1068+struct imm_type {
1069+ char *isuffix; /* Suffix String */
1070+ int itype; /* Suffix Type */
1071+ int otype; /* Offset Type */
1072+};
1073+
1074+/* These are NOT in assending order of type, GOTOFF is ahead to make
1075+ sure @GOTOFF does not get matched with @GOT */
1076+static struct imm_type imm_types[] = {
1077+ { "NONE", IMM_NONE , 0 },
1078+ { "GOTOFF", IMM_GOTOFF , GOTOFF_OFFSET },
1079+ { "GOT", IMM_GOT , GOT_OFFSET },
1080+ { "PLT", IMM_PLT , PLT_OFFSET },
1081+ { "TLSGD", IMM_TLSGD , TLSGD_OFFSET },
1082+ { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET },
1083+ { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET },
1084+ { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET },
1085+ { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET }
1086+};
1087+
1088+static int
1089+match_imm (const char *s, int *ilen)
1090+{
1091+ int i;
1092+ int slen;
1093+
1094+ /* Check for matching suffix */
1095+ for (i = 1; i < IMM_MAX; i++)
1096+ {
1097+ slen = strlen (imm_types[i].isuffix);
1098+
1099+ if (strncmp (imm_types[i].isuffix, s, slen) == 0)
1100+ {
1101+ *ilen = slen;
1102+ return imm_types[i].itype;
1103+ }
1104+ } /* for */
1105+ *ilen = 0;
1106+ return 0;
1107+}
1108+
1109+static int
1110+get_imm_otype (int itype)
1111+{
1112+ int i, otype;
1113+
1114+ otype = 0;
1115+ /* Check for matching itype */
1116+ for (i = 1; i < IMM_MAX; i++)
1117+ {
1118+ if (imm_types[i].itype == itype)
1119+ {
1120+ otype = imm_types[i].otype;
1121+ break;
1122+ }
1123+ }
1124+ return otype;
1125+}
1126
1127 static symbolS * GOT_symbol;
1128
1129@@ -612,6 +689,9 @@ parse_imm (char * s, expressionS * e, int min, int max)
1130 {
1131 char *new_pointer;
1132 char *atp;
1133+ int itype, ilen;
1134+
1135+ ilen = 0;
1136
1137 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
1138 for (atp = s; *atp != '@'; atp++)
1139@@ -620,26 +700,18 @@ parse_imm (char * s, expressionS * e, int min, int max)
1140
1141 if (*atp == '@')
1142 {
1143- if (strncmp (atp + 1, "GOTOFF", 5) == 0)
1144- {
1145- *atp = 0;
1146- e->X_md = IMM_GOTOFF;
1147- }
1148- else if (strncmp (atp + 1, "GOT", 3) == 0)
1149- {
1150- *atp = 0;
1151- e->X_md = IMM_GOT;
1152- }
1153- else if (strncmp (atp + 1, "PLT", 3) == 0)
1154- {
1155- *atp = 0;
1156- e->X_md = IMM_PLT;
1157- }
1158+ itype = match_imm (atp + 1, &ilen);
1159+ if (itype != 0)
1160+ {
1161+ *atp = 0;
1162+ e->X_md = itype;
1163+ }
1164 else
1165- {
1166- atp = NULL;
1167- e->X_md = 0;
1168- }
1169+ {
1170+ atp = NULL;
1171+ e->X_md = 0;
1172+ ilen = 0;
1173+ }
1174 *atp = 0;
1175 }
1176 else
1177@@ -655,6 +727,11 @@ parse_imm (char * s, expressionS * e, int min, int max)
1178
1179 new_pointer = parse_exp (s, e);
1180
1181+ if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20))
1182+ {
1183+ GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
1184+ }
1185+
1186 if (e->X_op == O_absent)
1187 ; /* An error message has already been emitted. */
1188 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
1189@@ -670,9 +747,7 @@ parse_imm (char * s, expressionS * e, int min, int max)
1190 {
1191 *atp = '@'; /* restore back (needed?) */
1192 if (new_pointer >= atp)
1193- new_pointer += (e->X_md == IMM_GOTOFF)?7:4;
1194- /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
1195-
1196+ new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
1197 }
1198 return new_pointer;
1199 }
1200@@ -792,7 +867,14 @@ tc_microblaze_fix_adjustable (struct fix *fixP)
1201 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
1202 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
1203 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
1204- || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT)
1205+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT
1206+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGD
1207+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSLD
1208+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
1209+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPREL
1210+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSDTPREL
1211+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
1212+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSTPREL)
1213 return 0;
1214
1215 return 1;
1216@@ -940,12 +1022,8 @@ md_assemble (char * str)
1217 opc = str_microblaze_rw_anchor;
1218 else
1219 opc = NULL;
1220- if (exp.X_md == IMM_GOT)
1221- subtype = GOT_OFFSET;
1222- else if (exp.X_md == IMM_PLT)
1223- subtype = PLT_OFFSET;
1224- else if (exp.X_md == IMM_GOTOFF)
1225- subtype = GOTOFF_OFFSET;
1226+ if (exp.X_md != 0)
1227+ subtype = get_imm_otype(exp.X_md);
1228 else
1229 subtype = opcode->inst_offset_type;
1230
1231@@ -1436,12 +1514,11 @@ md_assemble (char * str)
1232 char *opc = NULL;
1233 relax_substateT subtype;
1234
1235- if (exp.X_md == IMM_GOT)
1236- subtype = GOT_OFFSET;
1237- else if (exp.X_md == IMM_PLT)
1238- subtype = PLT_OFFSET;
1239+ if (exp.X_md != 0)
1240+ subtype = get_imm_otype(exp.X_md);
1241 else
1242 subtype = opcode->inst_offset_type;
1243+
1244 output = frag_var (rs_machine_dependent,
1245 isize * 2, /* maxm of 2 words. */
1246 isize, /* minm of 1 word. */
1247@@ -1503,12 +1580,11 @@ md_assemble (char * str)
1248 char *opc = NULL;
1249 relax_substateT subtype;
1250
1251- if (exp.X_md == IMM_GOT)
1252- subtype = GOT_OFFSET;
1253- else if (exp.X_md == IMM_PLT)
1254- subtype = PLT_OFFSET;
1255- else
1256+ if (exp.X_md != 0)
1257+ subtype = get_imm_otype(exp.X_md);
1258+ else
1259 subtype = opcode->inst_offset_type;
1260+
1261 output = frag_var (rs_machine_dependent,
1262 isize * 2, /* maxm of 2 words. */
1263 isize, /* minm of 1 word. */
1264@@ -1576,12 +1652,11 @@ md_assemble (char * str)
1265 char *opc = NULL;
1266 relax_substateT subtype;
1267
1268- if (exp.X_md == IMM_GOT)
1269- subtype = GOT_OFFSET;
1270- else if (exp.X_md == IMM_PLT)
1271- subtype = PLT_OFFSET;
1272- else
1273- subtype = opcode->inst_offset_type;
1274+ if (exp.X_md != 0)
1275+ subtype = get_imm_otype(exp.X_md);
1276+ else
1277+ subtype = opcode->inst_offset_type;
1278+
1279 output = frag_var (rs_machine_dependent,
1280 isize * 2, /* maxm of 2 words. */
1281 isize, /* minm of 1 word. */
1282@@ -1847,6 +1922,24 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1283 fragP->fr_fix += INST_WORD_SIZE * 2;
1284 fragP->fr_var = 0;
1285 break;
1286+ case TLSGD_OFFSET:
1287+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1288+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSGD);
1289+ fragP->fr_fix += INST_WORD_SIZE * 2;
1290+ fragP->fr_var = 0;
1291+ break;
1292+ case TLSLD_OFFSET:
1293+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1294+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSLD);
1295+ fragP->fr_fix += INST_WORD_SIZE * 2;
1296+ fragP->fr_var = 0;
1297+ break;
1298+ case TLSDTPREL_OFFSET:
1299+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1300+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSDTPREL);
1301+ fragP->fr_fix += INST_WORD_SIZE * 2;
1302+ fragP->fr_var = 0;
1303+ break;
1304
1305 default:
1306 abort ();
1307@@ -2028,6 +2121,11 @@ md_apply_fix (fixS * fixP,
1308 }
1309 break;
1310
1311+ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
1312+ case BFD_RELOC_MICROBLAZE_64_TLSGD:
1313+ case BFD_RELOC_MICROBLAZE_64_TLSLD:
1314+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
1315+
1316 case BFD_RELOC_MICROBLAZE_64_GOTPC:
1317 case BFD_RELOC_MICROBLAZE_64_GOT:
1318 case BFD_RELOC_MICROBLAZE_64_PLT:
1319@@ -2206,11 +2304,16 @@ md_estimate_size_before_relax (fragS * fragP,
1320 case GOT_OFFSET:
1321 case PLT_OFFSET:
1322 case GOTOFF_OFFSET:
1323+ case TLSGD_OFFSET:
1324+ case TLSLD_OFFSET:
1325+ case TLSTPREL_OFFSET:
1326+ case TLSDTPREL_OFFSET:
1327 fragP->fr_var = INST_WORD_SIZE*2;
1328 break;
1329 case DEFINED_RO_SEGMENT:
1330 case DEFINED_RW_SEGMENT:
1331 case DEFINED_PC_OFFSET:
1332+ case TLSDTPMOD_OFFSET:
1333 fragP->fr_var = INST_WORD_SIZE;
1334 break;
1335 default:
1336@@ -2294,6 +2397,13 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
1337 case BFD_RELOC_MICROBLAZE_64_PLT:
1338 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
1339 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
1340+ case BFD_RELOC_MICROBLAZE_64_TLSGD:
1341+ case BFD_RELOC_MICROBLAZE_64_TLSLD:
1342+ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
1343+ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
1344+ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
1345+ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
1346+ case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
1347 code = fixp->fx_r_type;
1348 break;
1349
1350diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
1351index d392231..c4d9821 100644
1352--- a/include/elf/microblaze.h
1353+++ b/include/elf/microblaze.h
1354@@ -50,6 +50,14 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
1355 RELOC_NUMBER (R_MICROBLAZE_GOTOFF_64, 19) /* Offset relative to GOT. */
1356 RELOC_NUMBER (R_MICROBLAZE_GOTOFF_32, 20) /* Offset relative to GOT. */
1357 RELOC_NUMBER (R_MICROBLAZE_COPY, 21) /* Runtime copy. */
1358+ RELOC_NUMBER (R_MICROBLAZE_TLS, 22) /* TLS Reloc */
1359+ RELOC_NUMBER (R_MICROBLAZE_TLSGD, 23) /* TLS General Dynamic */
1360+ RELOC_NUMBER (R_MICROBLAZE_TLSLD, 24) /* TLS Local Dynamic */
1361+ RELOC_NUMBER (R_MICROBLAZE_TLSDTPMOD32, 25) /* TLS Module ID */
1362+ RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL32, 26) /* TLS Offset Within TLS Block */
1363+ RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL64, 27) /* TLS Offset Within TLS Block */
1364+ RELOC_NUMBER (R_MICROBLAZE_TLSGOTTPREL32, 28) /* TLS Offset From Thread Pointer */
1365+ RELOC_NUMBER (R_MICROBLAZE_TLSTPREL32, 29) /* TLS Offset From Thread Pointer */
1366
1367 END_RELOC_NUMBERS (R_MICROBLAZE_max)
1368
1369--
13701.7.5.4
1371
diff --git a/recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch b/recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch
new file mode 100644
index 00000000..a2154785
--- /dev/null
+++ b/recipes-devtools/binutils/files/0013-19e05575d97b6dc83dae1b8309624da3102d7a74.patch
@@ -0,0 +1,310 @@
1From 19e05575d97b6dc83dae1b8309624da3102d7a74 Mon Sep 17 00:00:00 2001
2From: Michael Eager <eager@eagercon.com>
3Date: Tue, 18 Dec 2012 16:01:00 +0000
4Subject: PR ld/14736 bfd: * elf32-microblaze.c (calc_fixup): Add end
5 range. gas/testsuite: * gas/microblaze/relax_size.exp: New file -
6 test object size after linker relaxation *
7 gas/microblaze/relax_size.s: Likewise *
8 gas/microblaze/relax_size.elf: Likewise *
9 gas/microblaze/relax_size2.s: Likewise *
10 gas/microblaze/relax_size2.elf: Likewise
11
12Upstream-Status: Backport
13
14diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
15index 9d0a7ca..8aafe72 100644
16--- a/bfd/elf32-microblaze.c
17+++ b/bfd/elf32-microblaze.c
18@@ -1600,8 +1600,9 @@ microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
19 /* Calculate fixup value for reference. */
20
21 static int
22-calc_fixup (bfd_vma addr, asection *sec)
23+calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
24 {
25+ bfd_vma end = start + size;
26 int i, fixup = 0;
27
28 if (sec == NULL || sec->relax == NULL)
29@@ -1610,11 +1611,12 @@ calc_fixup (bfd_vma addr, asection *sec)
30 /* Look for addr in relax table, total fixup value. */
31 for (i = 0; i < sec->relax_count; i++)
32 {
33- if (addr <= sec->relax[i].addr)
34+ if (end <= sec->relax[i].addr)
35 break;
36+ if ((end != start) && (start > sec->relax[i].addr))
37+ continue;
38 fixup += sec->relax[i].size;
39 }
40-
41 return fixup;
42 }
43
44@@ -1827,7 +1829,7 @@ microblaze_elf_relax_section (bfd *abfd,
45 bfd_vma nraddr;
46
47 /* Get the new reloc address. */
48- nraddr = irel->r_offset - calc_fixup (irel->r_offset, sec);
49+ nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
50 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
51 {
52 default:
53@@ -1845,7 +1847,7 @@ microblaze_elf_relax_section (bfd *abfd,
54 /* Only handle relocs against .text. */
55 if (isym->st_shndx == shndx
56 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
57- irel->r_addend -= calc_fixup (irel->r_addend, sec);
58+ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
59 }
60 break;
61 case R_MICROBLAZE_NONE:
62@@ -1855,8 +1857,8 @@ microblaze_elf_relax_section (bfd *abfd,
63 int sfix, efix;
64 bfd_vma target_address;
65 target_address = irel->r_addend + irel->r_offset;
66- sfix = calc_fixup (irel->r_offset, sec);
67- efix = calc_fixup (target_address, sec);
68+ sfix = calc_fixup (irel->r_offset, 0, sec);
69+ efix = calc_fixup (target_address, 0, sec);
70 irel->r_addend -= (efix - sfix);
71 /* Should use HOWTO. */
72 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
73@@ -1870,8 +1872,8 @@ microblaze_elf_relax_section (bfd *abfd,
74 int sfix, efix;
75 bfd_vma target_address;
76 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
77- sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, sec);
78- efix = calc_fixup (target_address, sec);
79+ sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
80+ efix = calc_fixup (target_address, 0, sec);
81 irel->r_addend -= (efix - sfix);
82 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
83 + INST_WORD_SIZE, irel->r_addend);
84@@ -1934,7 +1936,7 @@ microblaze_elf_relax_section (bfd *abfd,
85 }
86
87 }
88- irelscan->r_addend -= calc_fixup (irelscan->r_addend, sec);
89+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
90 }
91 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
92 {
93@@ -1965,6 +1967,7 @@ microblaze_elf_relax_section (bfd *abfd,
94 }
95 irelscan->r_addend -= calc_fixup (irel->r_addend
96 + isym->st_value,
97+ 0,
98 sec);
99 }
100 }
101@@ -2005,7 +2008,7 @@ microblaze_elf_relax_section (bfd *abfd,
102 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
103 immediate = instr & 0x0000ffff;
104 target_address = immediate;
105- offset = calc_fixup (target_address, sec);
106+ offset = calc_fixup (target_address, 0, sec);
107 immediate -= offset;
108 irelscan->r_addend -= offset;
109 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
110@@ -2052,7 +2055,7 @@ microblaze_elf_relax_section (bfd *abfd,
111 + INST_WORD_SIZE);
112 immediate = (instr_hi & 0x0000ffff) << 16;
113 immediate |= (instr_lo & 0x0000ffff);
114- offset = calc_fixup (irelscan->r_addend, sec);
115+ offset = calc_fixup (irelscan->r_addend, 0, sec);
116 immediate -= offset;
117 irelscan->r_addend -= offset;
118 }
119@@ -2097,7 +2100,7 @@ microblaze_elf_relax_section (bfd *abfd,
120 immediate = (instr_hi & 0x0000ffff) << 16;
121 immediate |= (instr_lo & 0x0000ffff);
122 target_address = immediate;
123- offset = calc_fixup (target_address, sec);
124+ offset = calc_fixup (target_address, 0, sec);
125 immediate -= offset;
126 irelscan->r_addend -= offset;
127 microblaze_bfd_write_imm_value_64 (abfd, ocontents
128@@ -2112,24 +2115,30 @@ microblaze_elf_relax_section (bfd *abfd,
129 for (isym = isymbuf; isym < isymend; isym++)
130 {
131 if (isym->st_shndx == shndx)
132- isym->st_value =- calc_fixup (isym->st_value, sec);
133+ {
134+ isym->st_value -= calc_fixup (isym->st_value, 0, sec);
135+ if (isym->st_size)
136+ isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
137+ }
138 }
139
140 /* Now adjust the global symbols defined in this section. */
141 isym = isymbuf + symtab_hdr->sh_info;
142- isymend = isymbuf + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
143- for (sym_index = 0; isym < isymend; isym++, sym_index++)
144+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
145+ for (sym_index = 0; sym_index < symcount; sym_index++)
146 {
147 sym_hash = elf_sym_hashes (abfd)[sym_index];
148- if (isym->st_shndx == shndx
149- && (sym_hash->root.type == bfd_link_hash_defined
150+ if ((sym_hash->root.type == bfd_link_hash_defined
151 || sym_hash->root.type == bfd_link_hash_defweak)
152 && sym_hash->root.u.def.section == sec)
153- {
154- sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
155- sec);
156- }
157- }
158+ {
159+ sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
160+ 0, sec);
161+ if (sym_hash->size)
162+ sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
163+ sym_hash->size, sec);
164+ }
165+ }
166
167 /* Physically move the code and change the cooked size. */
168 dest = sec->relax[0].addr;
169diff --git a/gas/testsuite/gas/microblaze/relax_size.elf b/gas/testsuite/gas/microblaze/relax_size.elf
170new file mode 100644
171index 0000000..cf23ea6
172--- /dev/null
173+++ b/gas/testsuite/gas/microblaze/relax_size.elf
174@@ -0,0 +1,32 @@
175+
176+Symbol table '.symtab' contains 29 entries:
177+ Num: Value Size Type Bind Vis Ndx Name
178+ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
179+ 1: 00000050 0 SECTION LOCAL DEFAULT 1
180+ 2: 00000058 0 SECTION LOCAL DEFAULT 2
181+ 3: 00000000 0 FILE LOCAL DEFAULT ABS relax_size.o
182+ 4: 00000050 8 NOTYPE LOCAL DEFAULT 1 func
183+ 5: 00000058 0 NOTYPE LOCAL DEFAULT 1 label
184+ 6: 00000000 0 FILE LOCAL DEFAULT ABS
185+ 7: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _fdata
186+ 8: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _etext
187+ 9: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _essrw
188+ 10: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _heap_end
189+ 11: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _heap_start
190+ 12: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssro_size
191+ 13: 00000050 0 NOTYPE GLOBAL DEFAULT 1 _ftext
192+ 14: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _essro
193+ 15: 00000400 0 NOTYPE GLOBAL DEFAULT ABS _STACK_SIZE
194+ 16: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _HEAP_SIZE
195+ 17: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssrw_size
196+ 18: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _stack_end
197+ 19: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _edata
198+ 20: 00000458 0 NOTYPE GLOBAL DEFAULT 2 _end
199+ 21: 00000058 0 NOTYPE GLOBAL DEFAULT 1 _heap
200+ 22: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _ssro
201+ 23: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _ssrw
202+ 24: 00000458 0 NOTYPE GLOBAL DEFAULT 2 _stack
203+ 25: 00000050 0 NOTYPE GLOBAL DEFAULT ABS _TEXT_START_ADDR
204+ 26: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _frodata
205+ 27: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _fbss
206+ 28: 00000058 0 NOTYPE GLOBAL DEFAULT 2 _erodata
207diff --git a/gas/testsuite/gas/microblaze/relax_size.exp b/gas/testsuite/gas/microblaze/relax_size.exp
208new file mode 100644
209index 0000000..a733dc8
210--- /dev/null
211+++ b/gas/testsuite/gas/microblaze/relax_size.exp
212@@ -0,0 +1,25 @@
213+
214+proc ld_run { objects ldflags dest test } {
215+ set ld_output [target_link $objects $dest $ldflags]
216+}
217+
218+proc readelf_run { exec flags dest test } {
219+ set readelf [find_binutils_prog readelf]
220+ verbose -log "$readelf $flags $exec > $dest"
221+ catch "exec $readelf $flags $exec > $dest" readelf_output
222+}
223+
224+proc regexp_test { file1 file2 test } {
225+ if [regexp_diff $file1 $file2] then { fail $test } else { pass $test }
226+}
227+
228+global srcdir subdir
229+if [istarget microblaze*-*-elf] {
230+ foreach file [lsort [glob -nocomplain -- $srcdir/$subdir/relax_size*.s]] {
231+ set file [file rootname [file tail $file]]
232+ gas_run "$file.s" "-o $file.o" ""
233+ ld_run "$file.o" "-e 0 -N -relax" "$file.x" "linking $file.x"
234+ readelf_run "$file.x" "-s" "$file.elf" "readelf -s $file.x"
235+ regexp_test "$file.elf" "$srcdir/$subdir/$file.elf" "matching $file.elf"
236+ }
237+}
238diff --git a/gas/testsuite/gas/microblaze/relax_size.s b/gas/testsuite/gas/microblaze/relax_size.s
239new file mode 100644
240index 0000000..6b25977
241--- /dev/null
242+++ b/gas/testsuite/gas/microblaze/relax_size.s
243@@ -0,0 +1,7 @@
244+ .org 0
245+ .section .text
246+func:
247+ braid label
248+ nop
249+label:
250+ .size func, . - func
251diff --git a/gas/testsuite/gas/microblaze/relax_size2.elf b/gas/testsuite/gas/microblaze/relax_size2.elf
252new file mode 100644
253index 0000000..fbdcc0a
254--- /dev/null
255+++ b/gas/testsuite/gas/microblaze/relax_size2.elf
256@@ -0,0 +1,34 @@
257+
258+Symbol table '.symtab' contains 31 entries:
259+ Num: Value Size Type Bind Vis Ndx Name
260+ 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
261+ 1: 00000050 0 SECTION LOCAL DEFAULT 1
262+ 2: 00000060 0 SECTION LOCAL DEFAULT 2
263+ 3: 00000000 0 FILE LOCAL DEFAULT ABS relax_size2.o
264+ 4: 00000050 4 NOTYPE LOCAL DEFAULT 1 func
265+ 5: 00000054 0 NOTYPE LOCAL DEFAULT 1 label
266+ 6: 00000054 8 NOTYPE LOCAL DEFAULT 1 func2
267+ 7: 0000005c 0 NOTYPE LOCAL DEFAULT 1 label2
268+ 8: 00000000 0 FILE LOCAL DEFAULT ABS
269+ 9: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _fdata
270+ 10: 0000005c 0 NOTYPE GLOBAL DEFAULT 1 _etext
271+ 11: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _essrw
272+ 12: 00000060 0 NOTYPE GLOBAL DEFAULT 1 _heap_end
273+ 13: 00000060 0 NOTYPE GLOBAL DEFAULT 1 _heap_start
274+ 14: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssro_size
275+ 15: 00000050 0 NOTYPE GLOBAL DEFAULT 1 _ftext
276+ 16: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _essro
277+ 17: 00000400 0 NOTYPE GLOBAL DEFAULT ABS _STACK_SIZE
278+ 18: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _HEAP_SIZE
279+ 19: 00000000 0 NOTYPE GLOBAL DEFAULT ABS _ssrw_size
280+ 20: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _stack_end
281+ 21: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _edata
282+ 22: 00000460 0 NOTYPE GLOBAL DEFAULT 2 _end
283+ 23: 00000060 0 NOTYPE GLOBAL DEFAULT 1 _heap
284+ 24: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _ssro
285+ 25: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _ssrw
286+ 26: 00000460 0 NOTYPE GLOBAL DEFAULT 2 _stack
287+ 27: 00000050 0 NOTYPE GLOBAL DEFAULT ABS _TEXT_START_ADDR
288+ 28: 0000005c 0 NOTYPE GLOBAL DEFAULT 2 _frodata
289+ 29: 00000060 0 NOTYPE GLOBAL DEFAULT 2 _fbss
290+ 30: 0000005c 0 NOTYPE GLOBAL DEFAULT 2 _erodata
291diff --git a/gas/testsuite/gas/microblaze/relax_size2.s b/gas/testsuite/gas/microblaze/relax_size2.s
292new file mode 100644
293index 0000000..dedabfb
294--- /dev/null
295+++ b/gas/testsuite/gas/microblaze/relax_size2.s
296@@ -0,0 +1,11 @@
297+ .org 0
298+ .section .text
299+func:
300+ nop
301+label:
302+ .size func, . - func
303+func2:
304+ braid label2
305+ nop
306+label2:
307+ .size func2, . - func2
308--
3091.7.5.4
310
diff --git a/recipes-devtools/gcc/files/0001-Patch-microblaze-Enable-DWARF-exception-handling-sup.patch b/recipes-devtools/gcc/files/0001-Patch-microblaze-Enable-DWARF-exception-handling-sup.patch
new file mode 100644
index 00000000..d6549cad
--- /dev/null
+++ b/recipes-devtools/gcc/files/0001-Patch-microblaze-Enable-DWARF-exception-handling-sup.patch
@@ -0,0 +1,158 @@
1From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
2Subject: [PATCH 1/8] [Patch, microblaze]: Enable DWARF exception handling
3 support.
4
5Changelog
6
72013-03-18 Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8 David Holsgrove <david.holsgrove@xilinx.com>
9
10 * common/config/microblaze/microblaze-common.c: Remove
11 TARGET_EXCEPT_UNWIND_INFO definition.
12 * config/microblaze/microblaze-protos.h: Add
13 microblaze_eh_return prototype.
14 * gcc/config/microblaze/microblaze.c: (microblaze_must_save_register,
15 microblaze_expand_epilogue, microblaze_return_addr): Handle
16 calls_eh_return
17 (microblaze_eh_return): New function.
18 * gcc/config/microblaze/microblaze.h: Define RETURN_ADDR_OFFSET,
19 EH_RETURN_DATA_REGNO, MB_EH_STACKADJ_REGNUM, EH_RETURN_STACKADJ_RTX,
20 ASM_PREFERRED_EH_DATA_FORMAT
21 * gcc/config/microblaze/microblaze.md: Define eh_return pattern.
22
23Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
24Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
25Upstream-Status: Pending
26
27diff --git a/gcc/common/config/microblaze/microblaze-common.c b/gcc/common/config/microblaze/microblaze-common.c
28index 07a71fb..6c25a76 100644
29--- a/gcc/common/config/microblaze/microblaze-common.c
30+++ b/gcc/common/config/microblaze/microblaze-common.c
31@@ -37,7 +37,4 @@ static const struct default_options microblaze_option_optimization_table[] =
32 #undef TARGET_OPTION_OPTIMIZATION_TABLE
33 #define TARGET_OPTION_OPTIMIZATION_TABLE microblaze_option_optimization_table
34
35-#undef TARGET_EXCEPT_UNWIND_INFO
36-#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
37-
38 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
39diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
40index 34be76f..201390b 100644
41--- a/gcc/config/microblaze/microblaze-protos.h
42+++ b/gcc/config/microblaze/microblaze-protos.h
43@@ -54,6 +54,7 @@ extern bool microblaze_tls_referenced_p (rtx);
44 extern int symbol_mentioned_p (rtx);
45 extern int label_mentioned_p (rtx);
46 extern bool microblaze_cannot_force_const_mem (enum machine_mode, rtx);
47+extern void microblaze_eh_return (rtx op0);
48 #endif /* RTX_CODE */
49
50 /* Declare functions in microblaze-c.c. */
51diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
52index c121c2b..5f4bc60 100644
53--- a/gcc/config/microblaze/microblaze.c
54+++ b/gcc/config/microblaze/microblaze.c
55@@ -1896,6 +1896,11 @@ microblaze_must_save_register (int regno)
56 if (frame_pointer_needed && (regno == HARD_FRAME_POINTER_REGNUM))
57 return 1;
58
59+ if (crtl->calls_eh_return
60+ && regno == MB_ABI_SUB_RETURN_ADDR_REGNUM) {
61+ return 1;
62+ }
63+
64 if (!crtl->is_leaf)
65 {
66 if (regno == MB_ABI_SUB_RETURN_ADDR_REGNUM)
67@@ -1923,6 +1928,13 @@ microblaze_must_save_register (int regno)
68 return 1;
69 }
70
71+ if (crtl->calls_eh_return
72+ && (regno == EH_RETURN_DATA_REGNO (0)
73+ || regno == EH_RETURN_DATA_REGNO (1)))
74+ {
75+ return 1;
76+ }
77+
78 return 0;
79 }
80
81@@ -2939,6 +2951,12 @@ microblaze_expand_epilogue (void)
82 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, fsiz_rtx));
83 }
84
85+ if (crtl->calls_eh_return)
86+ emit_insn (gen_addsi3 (stack_pointer_rtx,
87+ stack_pointer_rtx,
88+ gen_rtx_raw_REG (SImode,
89+ MB_EH_STACKADJ_REGNUM)));
90+
91 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, GP_REG_FIRST +
92 MB_ABI_SUB_RETURN_ADDR_REGNUM)));
93 }
94@@ -3166,10 +3184,13 @@ microblaze_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
95 if (count != 0)
96 return NULL_RTX;
97
98- return gen_rtx_PLUS (Pmode,
99- get_hard_reg_initial_val (Pmode,
100- MB_ABI_SUB_RETURN_ADDR_REGNUM),
101- GEN_INT (8));
102+ return get_hard_reg_initial_val (Pmode,
103+ MB_ABI_SUB_RETURN_ADDR_REGNUM);
104+}
105+
106+void microblaze_eh_return (rtx op0)
107+{
108+ emit_insn (gen_movsi(gen_rtx_MEM(Pmode, stack_pointer_rtx), op0));
109 }
110
111 /* Queue an .ident string in the queue of top-level asm statements.
112diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
113index bc4d9a1..074b78e 100644
114--- a/gcc/config/microblaze/microblaze.h
115+++ b/gcc/config/microblaze/microblaze.h
116@@ -184,6 +184,21 @@ extern enum pipeline_type microblaze_pipe;
117 #define INCOMING_RETURN_ADDR_RTX \
118 gen_rtx_REG (VOIDmode, GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)
119
120+/* Specifies the offset from INCOMING_RETURN_ADDR_RTX and the actual return PC. */
121+#define RETURN_ADDR_OFFSET (8)
122+
123+/* Describe how we implement __builtin_eh_return. */
124+#define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? MB_ABI_FIRST_ARG_REGNUM + (N) : INVALID_REGNUM)
125+
126+#define MB_EH_STACKADJ_REGNUM MB_ABI_INT_RETURN_VAL2_REGNUM
127+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, MB_EH_STACKADJ_REGNUM)
128+
129+/* Select a format to encode pointers in exception handling data. CODE
130+ is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
131+ true if the symbol may be affected by dynamic relocations. */
132+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
133+ ((flag_pic || GLOBAL) ? DW_EH_PE_aligned : DW_EH_PE_absptr)
134+
135 /* Use DWARF 2 debugging information by default. */
136 #define DWARF2_DEBUGGING_INFO
137 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
138diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
139index 3618cad..4e7fe3b 100644
140--- a/gcc/config/microblaze/microblaze.md
141+++ b/gcc/config/microblaze/microblaze.md
142@@ -2221,3 +2221,13 @@
143 [(set_attr "type" "arith")
144 (set_attr "mode" "SI")
145 (set_attr "length" "4")])
146+
147+; This is used in compiling the unwind routines.
148+(define_expand "eh_return"
149+ [(use (match_operand 0 "general_operand" ""))]
150+ ""
151+ "
152+{
153+ microblaze_eh_return(operands[0]);
154+ DONE;
155+}")
156--
1571.7.5.4
158
diff --git a/recipes-devtools/gcc/files/0002-Patch-microblaze-Add-4-byte-implementation-for-atomi.patch b/recipes-devtools/gcc/files/0002-Patch-microblaze-Add-4-byte-implementation-for-atomi.patch
new file mode 100644
index 00000000..aefa13b0
--- /dev/null
+++ b/recipes-devtools/gcc/files/0002-Patch-microblaze-Add-4-byte-implementation-for-atomi.patch
@@ -0,0 +1,157 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH 2/8] [Patch, microblaze]: Add 4 byte implementation for
3 atomic builtin
4
5By providing this initial atomic implementation, gcc is able to generate the other atomic
6builtins by using a __sync_compare_and_swap loop
7
8Add __sync_lock_test_and_set 4 byte atomic builtin
9
10Changelog
11
122013-03-18 David Holsgrove <david.holsgrove@xilinx.com>
13
14 * gcc/config/microblaze/sync.md: New file.
15 * gcc/config/microblaze/microblaze.md: Add UNSPEC_SYNC_CAS,
16 UNSPEC_SYNC_XCHG and include sync.md.
17 * gcc/config/microblaze/microblaze.c: Add print_operand 'y'.
18 * gcc/config/microblaze/constraints.md: Add memory_contraint
19 'Q' which is a single register.
20
21Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
22Upstream-Status: Pending
23
24diff --git a/gcc/config/microblaze/constraints.md b/gcc/config/microblaze/constraints.md
25index c6fbc98..c9c1649 100644
26--- a/gcc/config/microblaze/constraints.md
27+++ b/gcc/config/microblaze/constraints.md
28@@ -70,3 +70,8 @@
29 "Double word operand."
30 (and (match_code "mem")
31 (match_test "double_memory_operand (op, GET_MODE (op))")))
32+
33+(define_memory_constraint "Q"
34+ "Memory operand which is a single register."
35+ (and (match_code "mem")
36+ (match_test "GET_CODE ( XEXP (op, 0)) == REG")))
37diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
38index 5f4bc60..1562e60 100644
39--- a/gcc/config/microblaze/microblaze.c
40+++ b/gcc/config/microblaze/microblaze.c
41@@ -2130,6 +2130,7 @@ microblaze_initial_elimination_offset (int from, int to)
42 't' print 't' for EQ, 'f' for NE
43 'm' Print 1<<operand.
44 'i' Print 'i' if MEM operand has immediate value
45+ 'y' Print 'y' if MEM operand is single register
46 'o' Print operand address+4
47 '?' Print 'd' if we use a branch with delay slot instead of normal branch.
48 'h' Print high word of const_double (int or float) value as hex
49@@ -2300,6 +2301,15 @@ print_operand (FILE * file, rtx op, int letter)
50 rtx op4 = adjust_address (op, GET_MODE (op), 4);
51 output_address (XEXP (op4, 0));
52 }
53+ else if (letter == 'y')
54+ {
55+ rtx mem_reg = XEXP (op, 0);
56+ if (GET_CODE (mem_reg) == REG)
57+ {
58+ register int regnum = REGNO (mem_reg);
59+ fprintf (file, "%s", reg_names[regnum]);
60+ }
61+ }
62 else
63 output_address (XEXP (op, 0));
64
65diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
66index 4e7fe3b..55cc730 100644
67--- a/gcc/config/microblaze/microblaze.md
68+++ b/gcc/config/microblaze/microblaze.md
69@@ -41,6 +41,8 @@
70 (UNSPEC_CMP 104) ;; signed compare
71 (UNSPEC_CMPU 105) ;; unsigned compare
72 (UNSPEC_TLS 106) ;; jump table
73+ (UNSPEC_SYNC_CAS 107) ;; Represent atomic compare swap.
74+ (UNSPEC_SYNC_XCHG 108) ;; Represent atomic exchange.
75 ])
76
77
78@@ -2231,3 +2233,5 @@
79 microblaze_eh_return(operands[0]);
80 DONE;
81 }")
82+
83+(include "sync.md")
84diff --git a/gcc/config/microblaze/sync.md b/gcc/config/microblaze/sync.md
85new file mode 100644
86index 0000000..0923825
87--- /dev/null
88+++ b/gcc/config/microblaze/sync.md
89@@ -0,0 +1,65 @@
90+;; Machine description for Xilinx MicroBlaze synchronization instructions.
91+;; Copyright (C) 2011, 2012
92+;; Free Software Foundation, Inc.
93+;;
94+;; This file is part of GCC.
95+;;
96+;; GCC is free software; you can redistribute it and/or modify
97+;; it under the terms of the GNU General Public License as published by
98+;; the Free Software Foundation; either version 3, or (at your option)
99+;; any later version.
100+;;
101+;; GCC is distributed in the hope that it will be useful,
102+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
103+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
104+;; GNU General Public License for more details.
105+;;
106+;; You should have received a copy of the GNU General Public License
107+;; along with GCC; see the file COPYING3. If not see
108+;; <http://www.gnu.org/licenses/>.
109+
110+
111+(define_insn "sync_compare_and_swapsi"
112+ [(set (match_operand:SI 0 "register_operand" "=&d") ;; retval
113+ (match_operand:SI 1 "nonimmediate_operand" "+Q")) ;; mem
114+ (set (match_dup 1)
115+ (unspec
116+ [(match_operand:SI 2 "register_operand" "d") ;; oldval
117+ (match_operand:SI 3 "register_operand" "d")] ;; newval
118+ UNSPEC_SYNC_CAS))
119+ (clobber (match_scratch:SI 4 "=&d"))] ;; scratch
120+ ""
121+ {
122+ output_asm_insn ("addc \tr0,r0,r0", operands);
123+ output_asm_insn ("lwx \t%0,%y1,r0", operands);
124+ output_asm_insn ("addic\t%4,r0,0", operands);
125+ output_asm_insn ("bnei \t%4,.-8", operands);
126+ output_asm_insn ("cmp \t%4,%0,%2", operands);
127+ output_asm_insn ("bnei \t%4,.+16", operands);
128+ output_asm_insn ("swx \t%3,%y1,r0", operands);
129+ output_asm_insn ("addic\t%4,r0,0", operands);
130+ output_asm_insn ("bnei \t%4,.-28", operands);
131+ return "";
132+ }
133+)
134+
135+(define_insn "sync_test_and_setsi"
136+ [(set (match_operand:SI 0 "register_operand" "=&d") ;; retval
137+ (match_operand:SI 1 "nonimmediate_operand" "+Q")) ;; mem
138+ (set (match_dup 1)
139+ (unspec
140+ [(match_operand:SI 2 "register_operand" "d")] ;; value
141+ UNSPEC_SYNC_XCHG))
142+ (clobber (match_scratch:SI 3 "=&d"))] ;; scratch
143+ ""
144+ {
145+ output_asm_insn ("addc \tr0,r0,r0", operands);
146+ output_asm_insn ("lwx \t%0,%y1,r0", operands);
147+ output_asm_insn ("addic\t%3,r0,0", operands);
148+ output_asm_insn ("bnei \t%3,.-8", operands);
149+ output_asm_insn ("swx \t%2,%y1,r0", operands);
150+ output_asm_insn ("addic\t%3,r0,0", operands);
151+ output_asm_insn ("bnei \t%3,.-20", operands);
152+ return "";
153+ }
154+)
155--
1561.7.5.4
157
diff --git a/recipes-devtools/gcc/files/0003-Patch-microblaze-Extend-jump-insn-to-accept-bri-to-S.patch b/recipes-devtools/gcc/files/0003-Patch-microblaze-Extend-jump-insn-to-accept-bri-to-S.patch
new file mode 100644
index 00000000..998dfa03
--- /dev/null
+++ b/recipes-devtools/gcc/files/0003-Patch-microblaze-Extend-jump-insn-to-accept-bri-to-S.patch
@@ -0,0 +1,35 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH 3/8] [Patch, microblaze]: Extend jump insn to accept bri to
3 SYMBOL_REFS
4
5Current insn checks if operand is a REG - if so, uses br
6else it bri to %l0 - using a label_ref print operand
7
8Check if operand is a SYMBOL_REF, and if so, use %0
9
10Changelog
11
122013-03-18 David Holsgrove <david.holsgrove@xilinx.com>
13
14 * gcc/config/microblaze/microblaze.md (jump):
15 Account for jumps to SYMBOL_REFs.
16
17Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
18Upstream-Status: Pending
19
20diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
21index 55cc730..49d8f01 100644
22--- a/gcc/config/microblaze/microblaze.md
23+++ b/gcc/config/microblaze/microblaze.md
24@@ -1729,6 +1729,8 @@
25 {
26 if (GET_CODE (operands[0]) == REG)
27 return "br%?\t%0";
28+ else if (GET_CODE (operands[0]) == SYMBOL_REF)
29+ return "bri%?\t%0";
30 else
31 return "bri%?\t%l0";
32 }
33--
341.7.5.4
35
diff --git a/recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch b/recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch
new file mode 100644
index 00000000..5d2665eb
--- /dev/null
+++ b/recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch
@@ -0,0 +1,116 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH 4/8] [Patch, microblaze]: Add TARGET_ASM_OUTPUT_MI_THUNK to
3 support varargs thunk
4
5Without this macro, generic gcc generates a less efficient thunk
6that calls function instead of jumping to it. The generic code
7does not support varargs and produces an error message on compilation;
8
9 error: generic thunk code fails for method
10 'virtual void C::f(const char*, ...)' which uses '...'
11
12Changelog
13
142013-03-18 David Holsgrove <david.holsgrove@xilinx.com>
15
16 * gcc/config/microblaze/microblaze.c: Add microblaze_asm_output_mi_thunk
17 and define TARGET_ASM_OUTPUT_MI_THUNK and TARGET_ASM_CAN_OUTPUT_MI_THUNK
18
19Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
20Upstream-Status: Pending
21
22diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
23index 1562e60..7418e49 100644
24--- a/gcc/config/microblaze/microblaze.c
25+++ b/gcc/config/microblaze/microblaze.c
26@@ -3005,6 +3005,74 @@ microblaze_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
27 }
28
29 static void
30+microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
31+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
32+ tree function)
33+{
34+ rtx this_rtx, insn, funexp;
35+
36+ reload_completed = 1;
37+ epilogue_completed = 1;
38+
39+ /* Mark the end of the (empty) prologue. */
40+ emit_note (NOTE_INSN_PROLOGUE_END);
41+
42+ /* Find the "this" pointer. If the function returns a structure,
43+ the structure return pointer is in MB_ABI_FIRST_ARG_REGNUM. */
44+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
45+ this_rtx = gen_rtx_REG (Pmode, (MB_ABI_FIRST_ARG_REGNUM + 1));
46+ else
47+ this_rtx = gen_rtx_REG (Pmode, MB_ABI_FIRST_ARG_REGNUM);
48+
49+ /* Apply the constant offset, if required. */
50+ if (delta)
51+ emit_insn (gen_addsi3 (this_rtx, this_rtx, GEN_INT (delta)));
52+
53+ /* Apply the offset from the vtable, if required. */
54+ if (vcall_offset)
55+ {
56+ rtx vcall_offset_rtx = GEN_INT (vcall_offset);
57+ rtx tmp = gen_rtx_REG (Pmode, MB_ABI_TEMP1_REGNUM);
58+
59+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
60+
61+ rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
62+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
63+
64+ emit_insn (gen_addsi3 (this_rtx, this_rtx, tmp));
65+ }
66+
67+ /* Generate a tail call to the target function. */
68+ if (!TREE_USED (function))
69+ {
70+ assemble_external (function);
71+ TREE_USED (function) = 1;
72+ }
73+ funexp = XEXP (DECL_RTL (function), 0);
74+
75+ if (flag_pic)
76+ {
77+ rtx scratch = gen_rtx_REG (Pmode, MB_ABI_TEMP2_REGNUM);
78+ rtx reg = microblaze_legitimize_address(funexp, scratch, FUNCTION_MODE);
79+ emit_move_insn (scratch, reg);
80+ funexp = scratch;
81+ }
82+
83+ emit_insn (gen_jump (funexp));
84+
85+ /* Run just enough of rest_of_compilation. This sequence was
86+ "borrowed" from rs6000.c. */
87+ insn = get_insns ();
88+ shorten_branches (insn);
89+ final_start_function (insn, file, 1);
90+ final (insn, file, 1);
91+ final_end_function ();
92+
93+ reload_completed = 0;
94+ epilogue_completed = 0;
95+}
96+
97+static void
98 microblaze_globalize_label (FILE * stream, const char *name)
99 {
100 fputs ("\t.globl\t", stream);
101@@ -3532,6 +3600,12 @@ microblaze_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x
102 #undef TARGET_SECONDARY_RELOAD
103 #define TARGET_SECONDARY_RELOAD microblaze_secondary_reload
104
105+#undef TARGET_ASM_OUTPUT_MI_THUNK
106+#define TARGET_ASM_OUTPUT_MI_THUNK microblaze_asm_output_mi_thunk
107+
108+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
109+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
110+
111 #undef TARGET_SCHED_ADJUST_COST
112 #define TARGET_SCHED_ADJUST_COST microblaze_adjust_cost
113
114--
1151.7.5.4
116
diff --git a/recipes-devtools/gcc/files/0005-Patch-microblaze-Add-fstack-usage-support.patch b/recipes-devtools/gcc/files/0005-Patch-microblaze-Add-fstack-usage-support.patch
new file mode 100644
index 00000000..ee3cb9db
--- /dev/null
+++ b/recipes-devtools/gcc/files/0005-Patch-microblaze-Add-fstack-usage-support.patch
@@ -0,0 +1,30 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH 5/8] [Patch, microblaze]: Add -fstack-usage support
3
4Changelog
5
62013-03-18 David Holsgrove <david.holsgrove@xilinx.com>
7
8 * gcc/config/microblaze/microblaze.c (microblaze_expand_prologue):
9 Add check for flag_stack_usage to enable -fstack-usage support
10
11Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
12Upstream-Status: Pending
13
14diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
15index 7418e49..4417289 100644
16--- a/gcc/config/microblaze/microblaze.c
17+++ b/gcc/config/microblaze/microblaze.c
18@@ -2790,6 +2790,9 @@ microblaze_expand_prologue (void)
19
20 fsiz = compute_frame_size (get_frame_size ());
21
22+ if (flag_stack_usage)
23+ current_function_static_stack_size = fsiz;
24+
25 /* If this function is a varargs function, store any registers that
26 would normally hold arguments ($5 - $10) on the stack. */
27 if (((TYPE_ARG_TYPES (fntype) != 0
28--
291.7.5.4
30
diff --git a/recipes-devtools/gcc/files/0006-Patch-microblaze-Remove-SECONDARY_MEMORY_NEEDED.patch b/recipes-devtools/gcc/files/0006-Patch-microblaze-Remove-SECONDARY_MEMORY_NEEDED.patch
new file mode 100644
index 00000000..923756a5
--- /dev/null
+++ b/recipes-devtools/gcc/files/0006-Patch-microblaze-Remove-SECONDARY_MEMORY_NEEDED.patch
@@ -0,0 +1,35 @@
1From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
2Subject: [PATCH 6/8] [Patch, microblaze]: Remove SECONDARY_MEMORY_NEEDED
3
4MicroBlaze doesn't have restrictions that would force us to
5reload regs via memory. Don't define SECONDARY_MEMORY_NEEDED.
6Fixes an ICE when compiling OpenSSL for linux.
7
8Changelog
9
102013-03-18 Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
12 * gcc/config/microblaze/microblaze.h: Remove SECONDARY_MEMORY_NEEDED
13 definition.
14
15Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
16Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@xilinx.com>
17Upstream-Status: Pending
18
19diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
20index 074b78e..add69e8 100644
21--- a/gcc/config/microblaze/microblaze.h
22+++ b/gcc/config/microblaze/microblaze.h
23@@ -422,9 +422,6 @@ extern enum reg_class microblaze_regno_to_class[];
24 || GET_MODE (X) == VOIDmode) \
25 ? (GR_REGS) : (CLASS))))
26
27-#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
28- (GET_MODE_CLASS (MODE) == MODE_INT)
29-
30 /* Stack layout; function entry, exit and calling. */
31
32 #define STACK_GROWS_DOWNWARD
33--
341.7.5.4
35
diff --git a/recipes-devtools/gcc/files/0007-Patch-microblaze-Add-SIZE_TYPE-and-PTRDIFF_TYPE-to-m.patch b/recipes-devtools/gcc/files/0007-Patch-microblaze-Add-SIZE_TYPE-and-PTRDIFF_TYPE-to-m.patch
new file mode 100644
index 00000000..33aee3a7
--- /dev/null
+++ b/recipes-devtools/gcc/files/0007-Patch-microblaze-Add-SIZE_TYPE-and-PTRDIFF_TYPE-to-m.patch
@@ -0,0 +1,39 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH 7/8] [Patch, microblaze]: Add SIZE_TYPE and PTRDIFF_TYPE to
3 microblaze.h
4
5Fixes warnings like;
6
7warning: format '%zX' expects argument of type 'size_t',
8but argument 3 has type 'unsigned int' [-Wformat]
9
10Changelog
11
122013-03-18 David Holsgrove <david.holsgrove@xilinx.com>
13
14 * gcc/config/microblaze/microblaze.h: Define SIZE_TYPE
15 and PTRDIFF_TYPE.
16
17Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
18Upstream-Status: Pending
19
20diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
21index add69e8..367e986 100644
22--- a/gcc/config/microblaze/microblaze.h
23+++ b/gcc/config/microblaze/microblaze.h
24@@ -228,6 +228,12 @@ extern enum pipeline_type microblaze_pipe;
25 #define STRICT_ALIGNMENT 1
26 #define PCC_BITFIELD_TYPE_MATTERS 1
27
28+#undef SIZE_TYPE
29+#define SIZE_TYPE "unsigned int"
30+
31+#undef PTRDIFF_TYPE
32+#define PTRDIFF_TYPE "int"
33+
34 #define CONSTANT_ALIGNMENT(EXP, ALIGN) \
35 ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
36 && (ALIGN) < BITS_PER_WORD \
37--
381.7.5.4
39
diff --git a/recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch b/recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch
new file mode 100644
index 00000000..4da74f3f
--- /dev/null
+++ b/recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch
@@ -0,0 +1,224 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH 8/8] [Patch, microblaze]: Add branch_compare instruction
3
4To facilitate optimization pass understanding of the conditional
5branch for microblaze, remove the UNSPEC'd signed_compare /
6unsigned_compare instructions, and replace with a complete
7branch_compare which will output_asm_insn the correct cmp/cmpu
8depending on comparison code and signed / unsigned.
9
10We then return the correct branch instruction.
11
12cbranchsi now calls an expanded microblaze_expand_conditional_branch
13function which will carry out compare against zero, compare EQ/NE,
14and all other compares appropriately.
15
16-funroll-loops optimization pass can now proceed
17
18Changelog
19
202013-03-19 David Holsgrove <david.holsgrove@xilinx.com>
21
22 * gcc/config/microblaze/predicates.md: Add cmp_op predicate.
23 * gcc/config/microblaze/microblaze.md: Add branch_compare
24 instruction which uses cmp_op predicate and emits cmp insn
25 before branch.
26 * gcc/config/microblaze/microblaze.c
27 (microblaze_emit_compare): Rename to
28 microblaze_expand_conditional_branch and consolidate logic.
29 (microblaze_expand_conditional_branch): emit branch_compare
30 insn instead of handling cmp op separate from branch insn.
31
32Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
33Upstream-Status: Pending
34
35diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
36index 4417289..84b58bf 100644
37--- a/gcc/config/microblaze/microblaze.c
38+++ b/gcc/config/microblaze/microblaze.c
39@@ -3336,65 +3336,45 @@ microblaze_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
40 emit_move_insn (mem, fnaddr);
41 }
42
43-/* Emit instruction to perform compare.
44- cmp is (compare_op op0 op1). */
45-static rtx
46-microblaze_emit_compare (enum machine_mode mode, rtx cmp, enum rtx_code *cmp_code)
47+/* Generate conditional branch -- first, generate test condition,
48+ second, generate correct branch instruction. */
49+
50+void
51+microblaze_expand_conditional_branch (enum machine_mode mode, rtx operands[])
52 {
53- rtx cmp_op0 = XEXP (cmp, 0);
54- rtx cmp_op1 = XEXP (cmp, 1);
55+ enum rtx_code code = GET_CODE (operands[0]);
56+ rtx cmp_op0 = operands[1];
57+ rtx cmp_op1 = operands[2];
58+ rtx label1 = operands[3];
59 rtx comp_reg = gen_reg_rtx (SImode);
60- enum rtx_code code = *cmp_code;
61-
62+ rtx condition;
63+
64 gcc_assert ((GET_CODE (cmp_op0) == REG) || (GET_CODE (cmp_op0) == SUBREG));
65
66 /* If comparing against zero, just test source reg. */
67- if (cmp_op1 == const0_rtx)
68- return cmp_op0;
69+ if (cmp_op1 == const0_rtx)
70+ {
71+ comp_reg = cmp_op0;
72+ condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx);
73+ emit_jump_insn (gen_condjump (condition, label1));
74+ }
75
76- if (code == EQ || code == NE)
77+ else if (code == EQ || code == NE)
78 {
79 /* Use xor for equal/not-equal comparison. */
80 emit_insn (gen_xorsi3 (comp_reg, cmp_op0, cmp_op1));
81+ condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx);
82+ emit_jump_insn (gen_condjump (condition, label1));
83 }
84- else if (code == GT || code == GTU || code == LE || code == LEU)
85- {
86- /* MicroBlaze compare is not symmetrical. */
87- /* Swap argument order. */
88- cmp_op1 = force_reg (mode, cmp_op1);
89- if (code == GT || code == LE)
90- emit_insn (gen_signed_compare (comp_reg, cmp_op0, cmp_op1));
91- else
92- emit_insn (gen_unsigned_compare (comp_reg, cmp_op0, cmp_op1));
93- /* Translate test condition. */
94- *cmp_code = swap_condition (code);
95- }
96- else /* if (code == GE || code == GEU || code == LT || code == LTU) */
97+ else
98 {
99+ /* Generate compare and branch in single instruction. */
100 cmp_op1 = force_reg (mode, cmp_op1);
101- if (code == GE || code == LT)
102- emit_insn (gen_signed_compare (comp_reg, cmp_op1, cmp_op0));
103- else
104- emit_insn (gen_unsigned_compare (comp_reg, cmp_op1, cmp_op0));
105+ condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1);
106+ emit_jump_insn (gen_branch_compare(condition, cmp_op0, cmp_op1, label1));
107 }
108-
109- return comp_reg;
110 }
111
112-/* Generate conditional branch -- first, generate test condition,
113- second, generate correct branch instruction. */
114-
115-void
116-microblaze_expand_conditional_branch (enum machine_mode mode, rtx operands[])
117-{
118- enum rtx_code code = GET_CODE (operands[0]);
119- rtx comp;
120- rtx condition;
121-
122- comp = microblaze_emit_compare (mode, operands[0], &code);
123- condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp, const0_rtx);
124- emit_jump_insn (gen_condjump (condition, operands[3]));
125-}
126
127 void
128 microblaze_expand_conditional_branch_sf (rtx operands[])
129diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
130index 49d8f01..9c1e1a3 100644
131--- a/gcc/config/microblaze/microblaze.md
132+++ b/gcc/config/microblaze/microblaze.md
133@@ -1624,28 +1624,6 @@
134 (set_attr "length" "4")]
135 )
136
137-(define_insn "signed_compare"
138- [(set (match_operand:SI 0 "register_operand" "=d")
139- (unspec
140- [(match_operand:SI 1 "register_operand" "d")
141- (match_operand:SI 2 "register_operand" "d")] UNSPEC_CMP))]
142- ""
143- "cmp\t%0,%1,%2"
144- [(set_attr "type" "arith")
145- (set_attr "mode" "SI")
146- (set_attr "length" "4")])
147-
148-(define_insn "unsigned_compare"
149- [(set (match_operand:SI 0 "register_operand" "=d")
150- (unspec
151- [(match_operand:SI 1 "register_operand" "d")
152- (match_operand:SI 2 "register_operand" "d")] UNSPEC_CMPU))]
153- ""
154- "cmpu\t%0,%1,%2"
155- [(set_attr "type" "arith")
156- (set_attr "mode" "SI")
157- (set_attr "length" "4")])
158-
159 ;;----------------------------------------------------------------
160 ;; Setting a register from an floating point comparison.
161 ;;----------------------------------------------------------------
162@@ -1719,6 +1697,47 @@
163 (set_attr "length" "4")]
164 )
165
166+(define_insn "branch_compare"
167+ [(set (pc)
168+ (if_then_else (match_operator:SI 0 "cmp_op"
169+ [(match_operand:SI 1 "register_operand" "d")
170+ (match_operand:SI 2 "register_operand" "d")
171+ ])
172+ (label_ref (match_operand 3))
173+ (pc)))
174+ (clobber(reg:SI R_TMP))]
175+ ""
176+ {
177+ operands[4] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
178+ enum rtx_code code = GET_CODE (operands[0]);
179+
180+ if (code == GT || code == LE)
181+ {
182+ output_asm_insn ("cmp\tr18,%z1,%z2", operands);
183+ code = swap_condition (code);
184+ }
185+ else if (code == GTU || code == LEU)
186+ {
187+ output_asm_insn ("cmpu\tr18,%z1,%z2", operands);
188+ code = swap_condition (code);
189+ }
190+ else if (code == GE || code == LT)
191+ {
192+ output_asm_insn ("cmp\tr18,%z2,%z1", operands);
193+ }
194+ else if (code == GEU || code == LTU)
195+ {
196+ output_asm_insn ("cmpu\tr18,%z2,%z1", operands);
197+ }
198+
199+ operands[0] = gen_rtx_fmt_ee (signed_condition (code), SImode, operands[4], const0_rtx);
200+ return "b%C0i%?\tr18,%3";
201+ }
202+ [(set_attr "type" "branch")
203+ (set_attr "mode" "none")
204+ (set_attr "length" "12")]
205+)
206+
207 ;;----------------------------------------------------------------
208 ;; Unconditional branches
209 ;;----------------------------------------------------------------
210diff --git a/gcc/config/microblaze/predicates.md b/gcc/config/microblaze/predicates.md
211index 5fd1bd4..2c23291 100644
212--- a/gcc/config/microblaze/predicates.md
213+++ b/gcc/config/microblaze/predicates.md
214@@ -119,3 +119,7 @@
215 ;; Test for valid PIC call operand
216 (define_predicate "call_insn_plt_operand"
217 (match_test "PLT_ADDR_P (op)"))
218+
219+;; Return if the code of this rtx pattern is a comparison.
220+(define_predicate "cmp_op"
221+ (match_code "gt,ge,gtu,geu,lt,le,ltu,leu"))
222--
2231.7.5.4
224
diff --git a/recipes-devtools/gcc/files/Patch-microblaze-Fix-bswaphi2-implementation.patch b/recipes-devtools/gcc/files/Patch-microblaze-Fix-bswaphi2-implementation.patch
new file mode 100644
index 00000000..b39dc4db
--- /dev/null
+++ b/recipes-devtools/gcc/files/Patch-microblaze-Fix-bswaphi2-implementation.patch
@@ -0,0 +1,44 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH] [Patch, microblaze]: Fix bswaphi2 implementation
3
4MicroBlaze insn swaph swaps the contents of register rA
5as two halfwords placing result in rD;
6
7(rD)[0:15] <- (rA)[16:31]
8(rD)[16:31] <- (rA)[0:15]
9
10gcc bswaphi2 is intended to reverse the order of the bytes
11in the half integer in rA
12
13(rD)[8:15] <- (rA)[0:7]
14(rD)[7:0] <- (rA)[8:15]
15(rD)[24:31] <- (rA)[16:23]
16(rD)[16:23] <- (rA)[24:31]
17
18Correct microblaze bswaphi2 insn pattern to be a
19swapb followed by swaph
20
21Reported-by: Nathan Rossi <nathan.rossi@xilinx.com>
22Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
23Upstream-Status: Pending
24---
25 gcc/config/microblaze/microblaze.md | 3 ++-
26 1 files changed, 2 insertions(+), 1 deletions(-)
27
28diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
29index ae4ade7..c7485fc 100644
30--- a/gcc/config/microblaze/microblaze.md
31+++ b/gcc/config/microblaze/microblaze.md
32@@ -367,7 +367,8 @@
33 [(set (match_operand:HI 0 "register_operand" "=r")
34 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
35 "TARGET_REORDER"
36- "swaph %0, %1"
37+ "swapb %0, %1
38+ swaph %0, %0"
39 )
40
41 ;;----------------------------------------------------------------
42--
431.7.1
44
diff --git a/recipes-devtools/gcc/files/Patch-microblaze-cstoresf4-add-mode-and-ordered_comp.patch b/recipes-devtools/gcc/files/Patch-microblaze-cstoresf4-add-mode-and-ordered_comp.patch
new file mode 100644
index 00000000..934e7fa9
--- /dev/null
+++ b/recipes-devtools/gcc/files/Patch-microblaze-cstoresf4-add-mode-and-ordered_comp.patch
@@ -0,0 +1,44 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH] [Patch, microblaze]: cstoresf4, add mode and
3 ordered_comparison_operator
4
5Add SImode to comparison operator, prevents ICE during combine
6rtl pass with error message;
7
8internal compiler error: in simplify_subreg, at simplify-rtx.c:5725
9
10Use ordered_comparison_operator predicate to limit operators to
11those fcmp can handle, and letting compiler reorder insns to
12accomodate unordered as necessary
13
14Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
15Upstream-Status: Pending
16---
17 gcc/config/microblaze/microblaze.md | 4 ++--
18 1 file changed, 2 insertions(+), 2 deletions(-)
19
20diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
21index 786dabb..e9b032b 100644
22--- a/gcc/config/microblaze/microblaze.md
23+++ b/gcc/config/microblaze/microblaze.md
24@@ -1650,7 +1650,7 @@
25 ;;----------------------------------------------------------------
26 (define_insn "cstoresf4"
27 [(set (match_operand:SI 0 "register_operand" "=r")
28- (match_operator 1 "comparison_operator"
29+ (match_operator:SI 1 "ordered_comparison_operator"
30 [(match_operand:SF 2 "register_operand" "r")
31 (match_operand:SF 3 "register_operand" "r")]))]
32 "TARGET_HARD_FLOAT"
33@@ -1679,7 +1679,7 @@
34
35 (define_expand "cbranchsf4"
36 [(set (pc)
37- (if_then_else (match_operator 0 "comparison_operator"
38+ (if_then_else (match_operator 0 "ordered_comparison_operator"
39 [(match_operand:SF 1 "register_operand")
40 (match_operand:SF 2 "register_operand")])
41 (label_ref (match_operand 3 ""))
42--
431.7.9.5
44
diff --git a/recipes-devtools/gcc/gcc-cross-canadian_4.8.bbappend b/recipes-devtools/gcc/gcc-cross-canadian_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-canadian_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/recipes-devtools/gcc/gcc-cross-initial_4.8.bbappend b/recipes-devtools/gcc/gcc-cross-initial_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-initial_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/recipes-devtools/gcc/gcc-cross_4.8.bbappend b/recipes-devtools/gcc/gcc-cross_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/recipes-devtools/gcc/gcc-crosssdk-initial_4.8.bbappend b/recipes-devtools/gcc/gcc-crosssdk-initial_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk-initial_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/recipes-devtools/gcc/gcc-crosssdk_4.8.bbappend b/recipes-devtools/gcc/gcc-crosssdk_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/recipes-devtools/gcc/gcc-microblaze-4.8.inc b/recipes-devtools/gcc/gcc-microblaze-4.8.inc
new file mode 100644
index 00000000..8acd32b2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-microblaze-4.8.inc
@@ -0,0 +1,15 @@
1
2# Add MicroBlaze Patches
3FILESEXTRAPATHS_append := "${THISDIR}/files:"
4SRC_URI_append += " \
5 file://0001-Patch-microblaze-Enable-DWARF-exception-handling-sup.patch \
6 file://0002-Patch-microblaze-Add-4-byte-implementation-for-atomi.patch \
7 file://0003-Patch-microblaze-Extend-jump-insn-to-accept-bri-to-S.patch \
8 file://0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch \
9 file://0005-Patch-microblaze-Add-fstack-usage-support.patch \
10 file://0006-Patch-microblaze-Remove-SECONDARY_MEMORY_NEEDED.patch \
11 file://0007-Patch-microblaze-Add-SIZE_TYPE-and-PTRDIFF_TYPE-to-m.patch \
12 file://0008-Patch-microblaze-Add-branch_compare-instruction.patch \
13 file://Patch-microblaze-Fix-bswaphi2-implementation.patch \
14 file://Patch-microblaze-cstoresf4-add-mode-and-ordered_comp.patch \
15 "
diff --git a/recipes-devtools/gcc/gcc-runtime_4.8.bbappend b/recipes-devtools/gcc/gcc-runtime_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-runtime_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/recipes-devtools/gcc/gcc_4.8.bbappend b/recipes-devtools/gcc/gcc_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/recipes-devtools/gcc/libgcc_4.8.bbappend b/recipes-devtools/gcc/libgcc_4.8.bbappend
new file mode 100644
index 00000000..e28b4dd0
--- /dev/null
+++ b/recipes-devtools/gcc/libgcc_4.8.bbappend
@@ -0,0 +1 @@
require gcc-microblaze-4.8.inc
diff --git a/site/microblaze-common b/site/microblaze-common
index c3d6c97c..58b8425a 100644
--- a/site/microblaze-common
+++ b/site/microblaze-common
@@ -3,7 +3,7 @@
3 3
4# glib-2.0 4# glib-2.0
5glib_cv_have_qsort_r=no 5glib_cv_have_qsort_r=no
6glib_cv_long_long_format=I64 6glib_cv_long_long_format=ll
7glib_cv_stack_grows=no 7glib_cv_stack_grows=no
8glib_cv_uscore=yes 8glib_cv_uscore=yes
9ac_cv_func_posix_getpwuid_r=yes 9ac_cv_func_posix_getpwuid_r=yes