diff options
Diffstat (limited to 'meta-microblaze/recipes-devtools/binutils/binutils/0015-Fixed-MB-x-relocation-issues.patch')
-rw-r--r-- | meta-microblaze/recipes-devtools/binutils/binutils/0015-Fixed-MB-x-relocation-issues.patch | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0015-Fixed-MB-x-relocation-issues.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0015-Fixed-MB-x-relocation-issues.patch new file mode 100644 index 00000000..e93e3476 --- /dev/null +++ b/meta-microblaze/recipes-devtools/binutils/binutils/0015-Fixed-MB-x-relocation-issues.patch | |||
@@ -0,0 +1,361 @@ | |||
1 | From da36307dff05dff1eebd44aec56f9bdc196ad632 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nagaraju Mekala <nmekala@xilix.com> | ||
3 | Date: Fri, 28 Sep 2018 12:04:55 +0530 | ||
4 | Subject: [PATCH 15/34] -Fixed MB-x relocation issues -Added imml for required | ||
5 | MB-x instructions | ||
6 | |||
7 | Conflicts: | ||
8 | bfd/elf64-microblaze.c | ||
9 | gas/config/tc-microblaze.c | ||
10 | |||
11 | Conflicts: | ||
12 | gas/config/tc-microblaze.c | ||
13 | --- | ||
14 | bfd/elf64-microblaze.c | 48 ++++++++++-- | ||
15 | gas/config/tc-microblaze.c | 155 ++++++++++++++++++++++++++----------- | ||
16 | gas/tc.h | 2 +- | ||
17 | 3 files changed, 152 insertions(+), 53 deletions(-) | ||
18 | |||
19 | diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c | ||
20 | index 0faa8de73c8..951bb36506d 100644 | ||
21 | --- a/bfd/elf64-microblaze.c | ||
22 | +++ b/bfd/elf64-microblaze.c | ||
23 | @@ -1552,6 +1552,14 @@ microblaze_elf_relocate_section (bfd *output_bfd, | ||
24 | bfd_put_16 (input_bfd, relocation & 0xffff, | ||
25 | contents + offset + endian); | ||
26 | |||
27 | + unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian); | ||
28 | + if (insn == 0xb2000000 || insn == 0xb2ffffff) | ||
29 | + { | ||
30 | + insn &= ~0x00ffffff; | ||
31 | + insn |= (relocation >> 16) & 0xffffff; | ||
32 | + bfd_put_32 (input_bfd, insn, | ||
33 | + contents + offset + endian); | ||
34 | + } | ||
35 | else | ||
36 | { | ||
37 | bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, | ||
38 | @@ -1659,6 +1667,14 @@ microblaze_elf_relocate_section (bfd *output_bfd, | ||
39 | bfd_put_16 (input_bfd, relocation & 0xffff, | ||
40 | contents + offset + endian); | ||
41 | } | ||
42 | + unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian); | ||
43 | + if (insn == 0xb2000000 || insn == 0xb2ffffff) | ||
44 | + { | ||
45 | + insn &= ~0x00ffffff; | ||
46 | + insn |= (relocation >> 16) & 0xffffff; | ||
47 | + bfd_put_32 (input_bfd, insn, | ||
48 | + contents + offset + endian); | ||
49 | + } | ||
50 | else | ||
51 | { | ||
52 | bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, | ||
53 | @@ -1769,9 +1785,19 @@ static void | ||
54 | microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) | ||
55 | { | ||
56 | unsigned long instr = bfd_get_32 (abfd, bfd_addr); | ||
57 | - instr &= ~0x0000ffff; | ||
58 | - instr |= (val & 0x0000ffff); | ||
59 | - bfd_put_32 (abfd, instr, bfd_addr); | ||
60 | + | ||
61 | + if (instr == 0xb2000000 || instr == 0xb2ffffff) | ||
62 | + { | ||
63 | + instr &= ~0x00ffffff; | ||
64 | + instr |= (val & 0xffffff); | ||
65 | + bfd_put_32 (abfd, instr, bfd_addr); | ||
66 | + } | ||
67 | + else | ||
68 | + { | ||
69 | + instr &= ~0x0000ffff; | ||
70 | + instr |= (val & 0x0000ffff); | ||
71 | + bfd_put_32 (abfd, instr, bfd_addr); | ||
72 | + } | ||
73 | } | ||
74 | |||
75 | /* Read-modify-write into the bfd, an immediate value into appropriate fields of | ||
76 | @@ -1783,10 +1809,18 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) | ||
77 | unsigned long instr_lo; | ||
78 | |||
79 | instr_hi = bfd_get_32 (abfd, bfd_addr); | ||
80 | - instr_hi &= ~0x0000ffff; | ||
81 | - instr_hi |= ((val >> 16) & 0x0000ffff); | ||
82 | - bfd_put_32 (abfd, instr_hi, bfd_addr); | ||
83 | - | ||
84 | + if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff) | ||
85 | + { | ||
86 | + instr_hi &= ~0x00ffffff; | ||
87 | + instr_hi |= (val >> 16) & 0xffffff; | ||
88 | + bfd_put_32 (abfd, instr_hi,bfd_addr); | ||
89 | + } | ||
90 | + else | ||
91 | + { | ||
92 | + instr_hi &= ~0x0000ffff; | ||
93 | + instr_hi |= ((val >> 16) & 0x0000ffff); | ||
94 | + bfd_put_32 (abfd, instr_hi, bfd_addr); | ||
95 | + } | ||
96 | instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE); | ||
97 | instr_lo &= ~0x0000ffff; | ||
98 | instr_lo |= (val & 0x0000ffff); | ||
99 | diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c | ||
100 | index 9d4dbc12ab3..a0e97231a41 100644 | ||
101 | --- a/gas/config/tc-microblaze.c | ||
102 | +++ b/gas/config/tc-microblaze.c | ||
103 | @@ -392,7 +392,7 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED) | ||
104 | Integer arg to pass to the function. */ | ||
105 | /* If the pseudo-op is not found in this table, it searches in the obj-elf.c, | ||
106 | and then in the read.c table. */ | ||
107 | -const pseudo_typeS md_pseudo_table[] = | ||
108 | +pseudo_typeS md_pseudo_table[] = | ||
109 | { | ||
110 | {"lcomm", microblaze_s_lcomm, 1}, | ||
111 | {"data", microblaze_s_data, 0}, | ||
112 | @@ -401,7 +401,7 @@ const pseudo_typeS md_pseudo_table[] = | ||
113 | {"data32", cons, 4}, /* Same as word. */ | ||
114 | {"ent", s_func, 0}, /* Treat ent as function entry point. */ | ||
115 | {"end", microblaze_s_func, 1}, /* Treat end as function end point. */ | ||
116 | - {"gpword", s_rva, 8}, /* gpword label => store resolved label address in data section. */ | ||
117 | + {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */ | ||
118 | {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */ | ||
119 | {"weakext", microblaze_s_weakext, 0}, | ||
120 | {"rodata", microblaze_s_rdata, 0}, | ||
121 | @@ -996,7 +996,7 @@ md_assemble (char * str) | ||
122 | unsigned reg2; | ||
123 | unsigned reg3; | ||
124 | unsigned isize; | ||
125 | - unsigned int immed = 0, immed2 = 0, temp; | ||
126 | + unsigned long immed = 0, immed2 = 0, temp; | ||
127 | expressionS exp; | ||
128 | char name[20]; | ||
129 | long immedl; | ||
130 | @@ -1118,8 +1118,9 @@ md_assemble (char * str) | ||
131 | as_fatal (_("lmi pseudo instruction should not use a label in imm field")); | ||
132 | else if (streq (name, "smi")) | ||
133 | as_fatal (_("smi pseudo instruction should not use a label in imm field")); | ||
134 | - | ||
135 | - if (reg2 == REG_ROSDP) | ||
136 | + if(streq (name, "lli") || streq (name, "sli")) | ||
137 | + opc = str_microblaze_64; | ||
138 | + else if (reg2 == REG_ROSDP) | ||
139 | opc = str_microblaze_ro_anchor; | ||
140 | else if (reg2 == REG_RWSDP) | ||
141 | opc = str_microblaze_rw_anchor; | ||
142 | @@ -1186,33 +1187,57 @@ md_assemble (char * str) | ||
143 | inst |= (immed << IMM_LOW) & IMM_MASK; | ||
144 | } | ||
145 | } | ||
146 | - else | ||
147 | - { | ||
148 | - temp = immed & 0xFFFF8000; | ||
149 | - if ((temp != 0) && (temp != 0xFFFF8000)) | ||
150 | - { | ||
151 | + else if (streq (name, "lli") || streq (name, "sli")) | ||
152 | + { | ||
153 | + temp = immed & 0xFFFFFF8000; | ||
154 | + if (temp != 0 && temp != 0xFFFFFF8000) | ||
155 | + { | ||
156 | /* Needs an immediate inst. */ | ||
157 | opcode1 | ||
158 | = (struct op_code_struct *) str_hash_find (opcode_hash_control, | ||
159 | - "imm"); | ||
160 | + "imml"); | ||
161 | if (opcode1 == NULL) | ||
162 | { | ||
163 | - as_bad (_("unknown opcode \"%s\""), "imm"); | ||
164 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
165 | return; | ||
166 | } | ||
167 | - | ||
168 | inst1 = opcode1->bit_sequence; | ||
169 | - inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; | ||
170 | + inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
171 | output[0] = INST_BYTE0 (inst1); | ||
172 | output[1] = INST_BYTE1 (inst1); | ||
173 | output[2] = INST_BYTE2 (inst1); | ||
174 | output[3] = INST_BYTE3 (inst1); | ||
175 | output = frag_more (isize); | ||
176 | - } | ||
177 | - inst |= (reg1 << RD_LOW) & RD_MASK; | ||
178 | - inst |= (reg2 << RA_LOW) & RA_MASK; | ||
179 | - inst |= (immed << IMM_LOW) & IMM_MASK; | ||
180 | - } | ||
181 | + } | ||
182 | + inst |= (reg1 << RD_LOW) & RD_MASK; | ||
183 | + inst |= (reg2 << RA_LOW) & RA_MASK; | ||
184 | + inst |= (immed << IMM_LOW) & IMM_MASK; | ||
185 | + } | ||
186 | + else | ||
187 | + { | ||
188 | + temp = immed & 0xFFFF8000; | ||
189 | + if ((temp != 0) && (temp != 0xFFFF8000)) | ||
190 | + { | ||
191 | + /* Needs an immediate inst. */ | ||
192 | + opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm"); | ||
193 | + if (opcode1 == NULL) | ||
194 | + { | ||
195 | + as_bad (_("unknown opcode \"%s\""), "imm"); | ||
196 | + return; | ||
197 | + } | ||
198 | + | ||
199 | + inst1 = opcode1->bit_sequence; | ||
200 | + inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; | ||
201 | + output[0] = INST_BYTE0 (inst1); | ||
202 | + output[1] = INST_BYTE1 (inst1); | ||
203 | + output[2] = INST_BYTE2 (inst1); | ||
204 | + output[3] = INST_BYTE3 (inst1); | ||
205 | + output = frag_more (isize); | ||
206 | + } | ||
207 | + inst |= (reg1 << RD_LOW) & RD_MASK; | ||
208 | + inst |= (reg2 << RA_LOW) & RA_MASK; | ||
209 | + inst |= (immed << IMM_LOW) & IMM_MASK; | ||
210 | + } | ||
211 | break; | ||
212 | |||
213 | case INST_TYPE_RD_R1_IMMS: | ||
214 | @@ -1842,12 +1867,20 @@ md_assemble (char * str) | ||
215 | case INST_TYPE_IMM: | ||
216 | if (streq (name, "imm")) | ||
217 | as_fatal (_("An IMM instruction should not be present in the .s file")); | ||
218 | - | ||
219 | - op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); | ||
220 | + if (microblaze_arch_size == 64) | ||
221 | + op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML); | ||
222 | + else | ||
223 | + op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); | ||
224 | |||
225 | if (exp.X_op != O_constant) | ||
226 | { | ||
227 | - char *opc = NULL; | ||
228 | + char *opc; | ||
229 | + if (microblaze_arch_size == 64 && (streq (name, "breai") || | ||
230 | + streq (name, "breaid") || | ||
231 | + streq (name, "brai") || streq (name, "braid"))) | ||
232 | + opc = str_microblaze_64; | ||
233 | + else | ||
234 | + opc = NULL; | ||
235 | relax_substateT subtype; | ||
236 | |||
237 | if (exp.X_md != 0) | ||
238 | @@ -1870,29 +1903,53 @@ md_assemble (char * str) | ||
239 | immed = exp.X_add_number; | ||
240 | } | ||
241 | |||
242 | - | ||
243 | - temp = immed & 0xFFFF8000; | ||
244 | - if ((temp != 0) && (temp != 0xFFFF8000)) | ||
245 | - { | ||
246 | - /* Needs an immediate inst. */ | ||
247 | - opcode1 | ||
248 | - = (struct op_code_struct *) str_hash_find (opcode_hash_control, | ||
249 | - "imm"); | ||
250 | - if (opcode1 == NULL) | ||
251 | - { | ||
252 | - as_bad (_("unknown opcode \"%s\""), "imm"); | ||
253 | - return; | ||
254 | + if (microblaze_arch_size == 64 && (streq (name, "breai") || | ||
255 | + streq (name, "breaid") || | ||
256 | + streq (name, "brai") || streq (name, "braid"))) | ||
257 | + { | ||
258 | + temp = immed & 0xFFFFFF8000; | ||
259 | + if (temp != 0) | ||
260 | + { | ||
261 | + /* Needs an immediate inst. */ | ||
262 | + opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imml"); | ||
263 | + if (opcode1 == NULL) | ||
264 | + { | ||
265 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
266 | + return; | ||
267 | + } | ||
268 | + inst1 = opcode1->bit_sequence; | ||
269 | + inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
270 | + output[0] = INST_BYTE0 (inst1); | ||
271 | + output[1] = INST_BYTE1 (inst1); | ||
272 | + output[2] = INST_BYTE2 (inst1); | ||
273 | + output[3] = INST_BYTE3 (inst1); | ||
274 | + output = frag_more (isize); | ||
275 | } | ||
276 | + inst |= (immed << IMM_LOW) & IMM_MASK; | ||
277 | + } | ||
278 | + else | ||
279 | + { | ||
280 | + temp = immed & 0xFFFF8000; | ||
281 | + if ((temp != 0) && (temp != 0xFFFF8000)) | ||
282 | + { | ||
283 | + /* Needs an immediate inst. */ | ||
284 | + opcode1 = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm"); | ||
285 | + if (opcode1 == NULL) | ||
286 | + { | ||
287 | + as_bad (_("unknown opcode \"%s\""), "imm"); | ||
288 | + return; | ||
289 | + } | ||
290 | |||
291 | - inst1 = opcode1->bit_sequence; | ||
292 | - inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; | ||
293 | - output[0] = INST_BYTE0 (inst1); | ||
294 | - output[1] = INST_BYTE1 (inst1); | ||
295 | - output[2] = INST_BYTE2 (inst1); | ||
296 | - output[3] = INST_BYTE3 (inst1); | ||
297 | - output = frag_more (isize); | ||
298 | - } | ||
299 | - inst |= (immed << IMM_LOW) & IMM_MASK; | ||
300 | + inst1 = opcode1->bit_sequence; | ||
301 | + inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; | ||
302 | + output[0] = INST_BYTE0 (inst1); | ||
303 | + output[1] = INST_BYTE1 (inst1); | ||
304 | + output[2] = INST_BYTE2 (inst1); | ||
305 | + output[3] = INST_BYTE3 (inst1); | ||
306 | + output = frag_more (isize); | ||
307 | + } | ||
308 | + inst |= (immed << IMM_LOW) & IMM_MASK; | ||
309 | + } | ||
310 | break; | ||
311 | |||
312 | case INST_TYPE_NONE: | ||
313 | @@ -2467,7 +2524,7 @@ md_apply_fix (fixS * fixP, | ||
314 | |||
315 | inst1 = opcode1->bit_sequence; | ||
316 | if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) | ||
317 | - inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
318 | + inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK; | ||
319 | if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64) | ||
320 | fixP->fx_r_type = BFD_RELOC_64; | ||
321 | if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL) | ||
322 | @@ -2636,7 +2693,14 @@ md_estimate_size_before_relax (fragS * fragP, | ||
323 | } | ||
324 | else | ||
325 | { | ||
326 | - fragP->fr_subtype = UNDEFINED_PC_OFFSET; | ||
327 | + if (fragP->fr_opcode != NULL) { | ||
328 | + if (streq (fragP->fr_opcode, str_microblaze_64)) | ||
329 | + fragP->fr_subtype = DEFINED_64_PC_OFFSET; | ||
330 | + else | ||
331 | + fragP->fr_subtype = UNDEFINED_PC_OFFSET; | ||
332 | + } | ||
333 | + else | ||
334 | + fragP->fr_subtype = UNDEFINED_PC_OFFSET; | ||
335 | fragP->fr_var = INST_WORD_SIZE*2; | ||
336 | } | ||
337 | break; | ||
338 | @@ -2913,6 +2977,7 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED) | ||
339 | case OPTION_M64: | ||
340 | //if (arg != NULL && strcmp (arg, "64") == 0) | ||
341 | microblaze_arch_size = 64; | ||
342 | + md_pseudo_table[7].poc_val = 8; | ||
343 | break; | ||
344 | default: | ||
345 | return 0; | ||
346 | diff --git a/gas/tc.h b/gas/tc.h | ||
347 | index 4a740f9bdd9..bb9a935a353 100644 | ||
348 | --- a/gas/tc.h | ||
349 | +++ b/gas/tc.h | ||
350 | @@ -22,7 +22,7 @@ | ||
351 | /* In theory (mine, at least!) the machine dependent part of the assembler | ||
352 | should only have to include one file. This one. -- JF */ | ||
353 | |||
354 | -extern const pseudo_typeS md_pseudo_table[]; | ||
355 | +extern pseudo_typeS md_pseudo_table[]; | ||
356 | |||
357 | const char * md_atof (int, char *, int *); | ||
358 | int md_parse_option (int, const char *); | ||
359 | -- | ||
360 | 2.37.1 (Apple Git-137.1) | ||
361 | |||