diff options
Diffstat (limited to 'meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch')
-rw-r--r-- | meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch new file mode 100644 index 00000000..a8d5a385 --- /dev/null +++ b/meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch | |||
@@ -0,0 +1,552 @@ | |||
1 | From 623f4e7ea6c18bec0e141c7471c7bd609bd9a6d7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mahesh Bodapati <mbodapat@xilinx.com> | ||
3 | Date: Mon, 26 Aug 2019 15:29:42 +0530 | ||
4 | Subject: [PATCH 28/40] [Patch,MicroBlaze] : double imml generation for 64 bit | ||
5 | values. | ||
6 | |||
7 | --- | ||
8 | gas/config/tc-microblaze.c | 324 ++++++++++++++++++++++++++++++------- | ||
9 | opcodes/microblaze-opc.h | 4 +- | ||
10 | 2 files changed, 264 insertions(+), 64 deletions(-) | ||
11 | |||
12 | diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c | ||
13 | index b4330652758..f5cc1e05f7e 100644 | ||
14 | --- a/gas/config/tc-microblaze.c | ||
15 | +++ b/gas/config/tc-microblaze.c | ||
16 | @@ -1022,7 +1022,7 @@ md_assemble (char * str) | ||
17 | char * op_start; | ||
18 | char * op_end; | ||
19 | char * temp_op_end; | ||
20 | - struct op_code_struct * opcode, *opcode1; | ||
21 | + struct op_code_struct * opcode, *opcode1, *opcode2; | ||
22 | char * output = NULL; | ||
23 | int nlen = 0; | ||
24 | int i; | ||
25 | @@ -1206,7 +1206,12 @@ md_assemble (char * str) | ||
26 | reg2 = 0; | ||
27 | } | ||
28 | if (strcmp (op_end, "")) | ||
29 | - op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); | ||
30 | + { | ||
31 | + if (microblaze_arch_size == 64) | ||
32 | + op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML); | ||
33 | + else | ||
34 | + op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); | ||
35 | + } | ||
36 | else | ||
37 | as_fatal (_("Error in statement syntax")); | ||
38 | |||
39 | @@ -1302,24 +1307,51 @@ md_assemble (char * str) | ||
40 | || streq (name, "lwi") || streq (name, "sbi") | ||
41 | || streq (name, "shi") || streq (name, "swi")))) | ||
42 | { | ||
43 | - temp = immed & 0xFFFFFF8000; | ||
44 | - if (temp != 0 && temp != 0xFFFFFF8000) | ||
45 | + temp = ((long long)immed) & 0xFFFFFFFFFFFF8000; | ||
46 | + if (temp != 0 && temp != 0xFFFFFFFFFFFF8000) | ||
47 | { | ||
48 | /* Needs an immediate inst. */ | ||
49 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
50 | - if (opcode1 == NULL) | ||
51 | + if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887) | ||
52 | + { | ||
53 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
54 | + if (opcode1 == NULL) | ||
55 | { | ||
56 | as_bad (_("unknown opcode \"%s\""), "imml"); | ||
57 | return; | ||
58 | } | ||
59 | inst1 = opcode1->bit_sequence; | ||
60 | - inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
61 | + inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
62 | output[0] = INST_BYTE0 (inst1); | ||
63 | output[1] = INST_BYTE1 (inst1); | ||
64 | output[2] = INST_BYTE2 (inst1); | ||
65 | output[3] = INST_BYTE3 (inst1); | ||
66 | output = frag_more (isize); | ||
67 | } | ||
68 | + else | ||
69 | + { | ||
70 | + opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
71 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
72 | + if (opcode1 == NULL || opcode2 == NULL) | ||
73 | + { | ||
74 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
75 | + return; | ||
76 | + } | ||
77 | + inst1 = opcode2->bit_sequence; | ||
78 | + inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK; | ||
79 | + output[0] = INST_BYTE0 (inst1); | ||
80 | + output[1] = INST_BYTE1 (inst1); | ||
81 | + output[2] = INST_BYTE2 (inst1); | ||
82 | + output[3] = INST_BYTE3 (inst1); | ||
83 | + output = frag_more (isize); | ||
84 | + inst1 = opcode1->bit_sequence; | ||
85 | + inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
86 | + output[0] = INST_BYTE0 (inst1); | ||
87 | + output[1] = INST_BYTE1 (inst1); | ||
88 | + output[2] = INST_BYTE2 (inst1); | ||
89 | + output[3] = INST_BYTE3 (inst1); | ||
90 | + output = frag_more (isize); | ||
91 | + } | ||
92 | + } | ||
93 | inst |= (reg1 << RD_LOW) & RD_MASK; | ||
94 | inst |= (reg2 << RA_LOW) & RA_MASK; | ||
95 | inst |= (immed << IMM_LOW) & IMM_MASK; | ||
96 | @@ -1330,14 +1362,13 @@ md_assemble (char * str) | ||
97 | if ((temp != 0) && (temp != 0xFFFF8000)) | ||
98 | { | ||
99 | /* Needs an immediate inst. */ | ||
100 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); | ||
101 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); | ||
102 | if (opcode1 == NULL) | ||
103 | { | ||
104 | as_bad (_("unknown opcode \"%s\""), "imm"); | ||
105 | return; | ||
106 | } | ||
107 | - | ||
108 | - inst1 = opcode1->bit_sequence; | ||
109 | + inst1 = opcode1->bit_sequence; | ||
110 | inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; | ||
111 | output[0] = INST_BYTE0 (inst1); | ||
112 | output[1] = INST_BYTE1 (inst1); | ||
113 | @@ -1578,7 +1609,7 @@ md_assemble (char * str) | ||
114 | as_fatal (_("Cannot use special register with this instruction")); | ||
115 | |||
116 | if (exp.X_op != O_constant) | ||
117 | - as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions")); | ||
118 | + as_fatal (_("Symbol used as immediate value for arithmetic long instructions")); | ||
119 | else | ||
120 | { | ||
121 | output = frag_more (isize); | ||
122 | @@ -1912,8 +1943,9 @@ md_assemble (char * str) | ||
123 | temp = immed & 0xFFFF8000; | ||
124 | if ((temp != 0) && (temp != 0xFFFF8000)) | ||
125 | { | ||
126 | + | ||
127 | /* Needs an immediate inst. */ | ||
128 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); | ||
129 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); | ||
130 | if (opcode1 == NULL) | ||
131 | { | ||
132 | as_bad (_("unknown opcode \"%s\""), "imm"); | ||
133 | @@ -1942,7 +1974,12 @@ md_assemble (char * str) | ||
134 | reg1 = 0; | ||
135 | } | ||
136 | if (strcmp (op_end, "")) | ||
137 | + { | ||
138 | + if(microblaze_arch_size == 64) | ||
139 | + op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML); | ||
140 | + else | ||
141 | op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); | ||
142 | + } | ||
143 | else | ||
144 | as_fatal (_("Error in statement syntax")); | ||
145 | |||
146 | @@ -1981,30 +2018,55 @@ md_assemble (char * str) | ||
147 | } | ||
148 | if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai")) | ||
149 | { | ||
150 | - temp = immed & 0xFFFFFF8000; | ||
151 | - if (temp != 0 && temp != 0xFFFFFF8000) | ||
152 | + temp = ((long long)immed) & 0xFFFFFFFFFFFF8000; | ||
153 | + if (temp != 0 && temp != 0xFFFFFFFFFFFF8000) | ||
154 | { | ||
155 | /* Needs an immediate inst. */ | ||
156 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
157 | + if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887) | ||
158 | + { | ||
159 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
160 | if (opcode1 == NULL) | ||
161 | { | ||
162 | as_bad (_("unknown opcode \"%s\""), "imml"); | ||
163 | return; | ||
164 | } | ||
165 | inst1 = opcode1->bit_sequence; | ||
166 | - inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
167 | + inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
168 | output[0] = INST_BYTE0 (inst1); | ||
169 | output[1] = INST_BYTE1 (inst1); | ||
170 | output[2] = INST_BYTE2 (inst1); | ||
171 | output[3] = INST_BYTE3 (inst1); | ||
172 | output = frag_more (isize); | ||
173 | } | ||
174 | + else { | ||
175 | + opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
176 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
177 | + if (opcode1 == NULL || opcode2 == NULL) | ||
178 | + { | ||
179 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
180 | + return; | ||
181 | + } | ||
182 | + inst1 = opcode2->bit_sequence; | ||
183 | + inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK; | ||
184 | + output[0] = INST_BYTE0 (inst1); | ||
185 | + output[1] = INST_BYTE1 (inst1); | ||
186 | + output[2] = INST_BYTE2 (inst1); | ||
187 | + output[3] = INST_BYTE3 (inst1); | ||
188 | + output = frag_more (isize); | ||
189 | + inst1 = opcode1->bit_sequence; | ||
190 | + inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
191 | + output[0] = INST_BYTE0 (inst1); | ||
192 | + output[1] = INST_BYTE1 (inst1); | ||
193 | + output[2] = INST_BYTE2 (inst1); | ||
194 | + output[3] = INST_BYTE3 (inst1); | ||
195 | + output = frag_more (isize); | ||
196 | + } | ||
197 | + } | ||
198 | inst |= (reg1 << RD_LOW) & RD_MASK; | ||
199 | inst |= (immed << IMM_LOW) & IMM_MASK; | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | - | ||
204 | temp = immed & 0xFFFF8000; | ||
205 | if ((temp != 0) && (temp != 0xFFFF8000)) | ||
206 | { | ||
207 | @@ -2090,25 +2152,50 @@ md_assemble (char * str) | ||
208 | streq (name, "breaid") || | ||
209 | streq (name, "brai") || streq (name, "braid"))) | ||
210 | { | ||
211 | - temp = immed & 0xFFFFFF8000; | ||
212 | + temp = immed & 0xFFFFFFFFFFFF8000; | ||
213 | if (temp != 0) | ||
214 | { | ||
215 | /* Needs an immediate inst. */ | ||
216 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
217 | + if (((long long)immed) > (long long)-549755813888 && ((long long)immed) < (long long)549755813887) | ||
218 | + { | ||
219 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
220 | if (opcode1 == NULL) | ||
221 | { | ||
222 | as_bad (_("unknown opcode \"%s\""), "imml"); | ||
223 | return; | ||
224 | } | ||
225 | - | ||
226 | inst1 = opcode1->bit_sequence; | ||
227 | - inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
228 | + inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
229 | + output[0] = INST_BYTE0 (inst1); | ||
230 | + output[1] = INST_BYTE1 (inst1); | ||
231 | + output[2] = INST_BYTE2 (inst1); | ||
232 | + output[3] = INST_BYTE3 (inst1); | ||
233 | + output = frag_more (isize); | ||
234 | + } | ||
235 | + else { | ||
236 | + opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
237 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
238 | + if (opcode1 == NULL || opcode2 == NULL) | ||
239 | + { | ||
240 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
241 | + return; | ||
242 | + } | ||
243 | + inst1 = opcode2->bit_sequence; | ||
244 | + inst1 |= ((immed & 0xFFFFFF0000000000L) >> 40) & IMML_MASK; | ||
245 | + output[0] = INST_BYTE0 (inst1); | ||
246 | + output[1] = INST_BYTE1 (inst1); | ||
247 | + output[2] = INST_BYTE2 (inst1); | ||
248 | + output[3] = INST_BYTE3 (inst1); | ||
249 | + output = frag_more (isize); | ||
250 | + inst1 = opcode1->bit_sequence; | ||
251 | + inst1 |= ((immed & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
252 | output[0] = INST_BYTE0 (inst1); | ||
253 | output[1] = INST_BYTE1 (inst1); | ||
254 | output[2] = INST_BYTE2 (inst1); | ||
255 | output[3] = INST_BYTE3 (inst1); | ||
256 | output = frag_more (isize); | ||
257 | } | ||
258 | + } | ||
259 | inst |= (immed << IMM_LOW) & IMM_MASK; | ||
260 | } | ||
261 | else | ||
262 | @@ -2208,21 +2295,45 @@ md_assemble (char * str) | ||
263 | { | ||
264 | output = frag_more (isize); | ||
265 | immedl = exp.X_add_number; | ||
266 | - | ||
267 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
268 | - if (opcode1 == NULL) | ||
269 | - { | ||
270 | - as_bad (_("unknown opcode \"%s\""), "imml"); | ||
271 | - return; | ||
272 | - } | ||
273 | - | ||
274 | - inst1 = opcode1->bit_sequence; | ||
275 | - inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
276 | - output[0] = INST_BYTE0 (inst1); | ||
277 | - output[1] = INST_BYTE1 (inst1); | ||
278 | - output[2] = INST_BYTE2 (inst1); | ||
279 | - output[3] = INST_BYTE3 (inst1); | ||
280 | - output = frag_more (isize); | ||
281 | + if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887) | ||
282 | + { | ||
283 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
284 | + if (opcode1 == NULL) | ||
285 | + { | ||
286 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
287 | + return; | ||
288 | + } | ||
289 | + inst1 = opcode1->bit_sequence; | ||
290 | + inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
291 | + output[0] = INST_BYTE0 (inst1); | ||
292 | + output[1] = INST_BYTE1 (inst1); | ||
293 | + output[2] = INST_BYTE2 (inst1); | ||
294 | + output[3] = INST_BYTE3 (inst1); | ||
295 | + output = frag_more (isize); | ||
296 | + } | ||
297 | + else { | ||
298 | + opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
299 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
300 | + if (opcode2 == NULL || opcode1 == NULL) | ||
301 | + { | ||
302 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
303 | + return; | ||
304 | + } | ||
305 | + inst1 = opcode2->bit_sequence; | ||
306 | + inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK; | ||
307 | + output[0] = INST_BYTE0 (inst1); | ||
308 | + output[1] = INST_BYTE1 (inst1); | ||
309 | + output[2] = INST_BYTE2 (inst1); | ||
310 | + output[3] = INST_BYTE3 (inst1); | ||
311 | + output = frag_more (isize); | ||
312 | + inst1 = opcode1->bit_sequence; | ||
313 | + inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
314 | + output[0] = INST_BYTE0 (inst1); | ||
315 | + output[1] = INST_BYTE1 (inst1); | ||
316 | + output[2] = INST_BYTE2 (inst1); | ||
317 | + output[3] = INST_BYTE3 (inst1); | ||
318 | + output = frag_more (isize); | ||
319 | + } | ||
320 | } | ||
321 | |||
322 | inst |= (reg1 << RD_LOW) & RD_MASK; | ||
323 | @@ -2271,21 +2382,46 @@ md_assemble (char * str) | ||
324 | { | ||
325 | output = frag_more (isize); | ||
326 | immedl = exp.X_add_number; | ||
327 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
328 | - if (opcode1 == NULL) | ||
329 | - { | ||
330 | - as_bad (_("unknown opcode \"%s\""), "imml"); | ||
331 | - return; | ||
332 | - } | ||
333 | - | ||
334 | + if (((long long)immedl) > (long long)-549755813888 && ((long long)immedl) < (long long)549755813887) | ||
335 | + { | ||
336 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
337 | + if (opcode1 == NULL) | ||
338 | + { | ||
339 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
340 | + return; | ||
341 | + } | ||
342 | + inst1 = opcode1->bit_sequence; | ||
343 | + inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
344 | + output[0] = INST_BYTE0 (inst1); | ||
345 | + output[1] = INST_BYTE1 (inst1); | ||
346 | + output[2] = INST_BYTE2 (inst1); | ||
347 | + output[3] = INST_BYTE3 (inst1); | ||
348 | + output = frag_more (isize); | ||
349 | + } | ||
350 | + else { | ||
351 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
352 | + opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
353 | + if (opcode2 == NULL || opcode1 == NULL) | ||
354 | + { | ||
355 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
356 | + return; | ||
357 | + } | ||
358 | + inst1 = opcode2->bit_sequence; | ||
359 | + inst1 |= ((immedl & 0xFFFFFF0000000000L) >> 40) & IMML_MASK; | ||
360 | + output[0] = INST_BYTE0 (inst1); | ||
361 | + output[1] = INST_BYTE1 (inst1); | ||
362 | + output[2] = INST_BYTE2 (inst1); | ||
363 | + output[3] = INST_BYTE3 (inst1); | ||
364 | + output = frag_more (isize); | ||
365 | inst1 = opcode1->bit_sequence; | ||
366 | - inst1 |= ((immedl & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK; | ||
367 | + inst1 |= ((immedl & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
368 | output[0] = INST_BYTE0 (inst1); | ||
369 | output[1] = INST_BYTE1 (inst1); | ||
370 | output[2] = INST_BYTE2 (inst1); | ||
371 | output[3] = INST_BYTE3 (inst1); | ||
372 | output = frag_more (isize); | ||
373 | } | ||
374 | + } | ||
375 | |||
376 | inst |= (reg1 << RA_LOW) & RA_MASK; | ||
377 | inst |= (immedl << IMM_LOW) & IMM_MASK; | ||
378 | @@ -2565,8 +2701,8 @@ md_apply_fix (fixS * fixP, | ||
379 | /* Note: use offsetT because it is signed, valueT is unsigned. */ | ||
380 | offsetT val = (offsetT) * valp; | ||
381 | int i; | ||
382 | - struct op_code_struct * opcode1; | ||
383 | - unsigned long inst1; | ||
384 | + struct op_code_struct * opcode1, * opcode2; | ||
385 | + unsigned long inst1,inst2; | ||
386 | |||
387 | symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>"); | ||
388 | |||
389 | @@ -2749,30 +2885,75 @@ md_apply_fix (fixS * fixP, | ||
390 | case BFD_RELOC_MICROBLAZE_64_TEXTREL: | ||
391 | case BFD_RELOC_MICROBLAZE_64: | ||
392 | case BFD_RELOC_MICROBLAZE_64_PCREL: | ||
393 | - /* Add an imm instruction. First save the current instruction. */ | ||
394 | - for (i = 0; i < INST_WORD_SIZE; i++) | ||
395 | - buf[i + INST_WORD_SIZE] = buf[i]; | ||
396 | if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64 | ||
397 | || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL) | ||
398 | { | ||
399 | /* Generate the imm instruction. */ | ||
400 | + if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887) | ||
401 | + { | ||
402 | + /* Add an imm instruction. First save the current instruction. */ | ||
403 | + for (i = 0; i < INST_WORD_SIZE; i++) | ||
404 | + buf[i + INST_WORD_SIZE] = buf[i]; | ||
405 | opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
406 | if (opcode1 == NULL) | ||
407 | - { | ||
408 | - as_bad (_("unknown opcode \"%s\""), "imml"); | ||
409 | - return; | ||
410 | - } | ||
411 | + { | ||
412 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
413 | + return; | ||
414 | + } | ||
415 | |||
416 | inst1 = opcode1->bit_sequence; | ||
417 | if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) | ||
418 | - inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK; | ||
419 | + inst1 |= ((val & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
420 | + if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64) | ||
421 | + fixP->fx_r_type = BFD_RELOC_64; | ||
422 | + if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL) | ||
423 | + fixP->fx_r_type = BFD_RELOC_64_PCREL; | ||
424 | + buf[0] = INST_BYTE0 (inst1); | ||
425 | + buf[1] = INST_BYTE1 (inst1); | ||
426 | + buf[2] = INST_BYTE2 (inst1); | ||
427 | + buf[3] = INST_BYTE3 (inst1); | ||
428 | + } | ||
429 | + else { | ||
430 | + /* Add an imm instruction. First save the current instruction. */ | ||
431 | + for (i = 0; i < INST_WORD_SIZE; i++) | ||
432 | + buf[i + INST_WORD_SIZE + 4] = buf[i]; | ||
433 | + | ||
434 | + opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
435 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
436 | + if (opcode1 == NULL || opcode2 ==NULL) | ||
437 | + { | ||
438 | + as_bad (_("unknown opcode \"%s\""), "imml"); | ||
439 | + return; | ||
440 | + } | ||
441 | + inst1 = opcode2->bit_sequence; | ||
442 | + if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) | ||
443 | + inst1 |= ((val & 0x000000FFFFFF0000L) >> 40) & IMML_MASK; | ||
444 | + if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64) | ||
445 | + fixP->fx_r_type = BFD_RELOC_64; | ||
446 | + if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL) | ||
447 | + fixP->fx_r_type = BFD_RELOC_64_PCREL; | ||
448 | + inst2 = opcode1->bit_sequence; | ||
449 | + if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) | ||
450 | + inst1 |= ((val & 0x000000FFFFFF0000L) >> 16) & IMML_MASK; | ||
451 | if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64) | ||
452 | - fixP->fx_r_type = BFD_RELOC_64; | ||
453 | + fixP->fx_r_type = BFD_RELOC_64; | ||
454 | if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL) | ||
455 | - fixP->fx_r_type = BFD_RELOC_64_PCREL; | ||
456 | + fixP->fx_r_type = BFD_RELOC_64_PCREL; | ||
457 | + buf[0] = INST_BYTE0 (inst1); | ||
458 | + buf[1] = INST_BYTE1 (inst1); | ||
459 | + buf[2] = INST_BYTE2 (inst1); | ||
460 | + buf[3] = INST_BYTE3 (inst1); | ||
461 | + buf[4] = INST_BYTE0 (inst2); | ||
462 | + buf[5] = INST_BYTE1 (inst2); | ||
463 | + buf[6] = INST_BYTE2 (inst2); | ||
464 | + buf[7] = INST_BYTE3 (inst2); | ||
465 | + } | ||
466 | } | ||
467 | else | ||
468 | { | ||
469 | + /* Add an imm instruction. First save the current instruction. */ | ||
470 | + for (i = 0; i < INST_WORD_SIZE; i++) | ||
471 | + buf[i + INST_WORD_SIZE] = buf[i]; | ||
472 | /* Generate the imm instruction. */ | ||
473 | opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); | ||
474 | if (opcode1 == NULL) | ||
475 | @@ -2784,12 +2965,11 @@ md_apply_fix (fixS * fixP, | ||
476 | inst1 = opcode1->bit_sequence; | ||
477 | if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) | ||
478 | inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK; | ||
479 | - } | ||
480 | buf[0] = INST_BYTE0 (inst1); | ||
481 | buf[1] = INST_BYTE1 (inst1); | ||
482 | buf[2] = INST_BYTE2 (inst1); | ||
483 | buf[3] = INST_BYTE3 (inst1); | ||
484 | - | ||
485 | + } | ||
486 | /* Add the value only if the symbol is defined. */ | ||
487 | if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) | ||
488 | { | ||
489 | @@ -2821,21 +3001,41 @@ md_apply_fix (fixS * fixP, | ||
490 | /* Add an imm instruction. First save the current instruction. */ | ||
491 | for (i = 0; i < INST_WORD_SIZE; i++) | ||
492 | buf[i + INST_WORD_SIZE] = buf[i]; | ||
493 | - if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC) | ||
494 | - opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
495 | + if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC) { | ||
496 | + if (((long long)val) > (long long)-549755813888 && ((long long)val) < (long long)549755813887) | ||
497 | + { | ||
498 | + for (i = 0; i < INST_WORD_SIZE; i++) | ||
499 | + buf[i + INST_WORD_SIZE] = buf[i]; | ||
500 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
501 | + } | ||
502 | + else { | ||
503 | + for (i = 0; i < INST_WORD_SIZE; i++) | ||
504 | + buf[i + INST_WORD_SIZE + 4] = buf[i]; | ||
505 | + opcode2 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
506 | + opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml"); | ||
507 | + inst2 = opcode2->bit_sequence; | ||
508 | + | ||
509 | + /* We can fixup call to a defined non-global address | ||
510 | + * within the same section only. */ | ||
511 | + buf[4] = INST_BYTE0 (inst2); | ||
512 | + buf[5] = INST_BYTE1 (inst2); | ||
513 | + buf[6] = INST_BYTE2 (inst2); | ||
514 | + buf[7] = INST_BYTE3 (inst2); | ||
515 | + } | ||
516 | + } | ||
517 | else | ||
518 | opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); | ||
519 | if (opcode1 == NULL) | ||
520 | { | ||
521 | + for (i = 0; i < INST_WORD_SIZE; i++) | ||
522 | + buf[i + INST_WORD_SIZE] = buf[i]; | ||
523 | if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC) | ||
524 | as_bad (_("unknown opcode \"%s\""), "imml"); | ||
525 | else | ||
526 | as_bad (_("unknown opcode \"%s\""), "imm"); | ||
527 | return; | ||
528 | } | ||
529 | - | ||
530 | inst1 = opcode1->bit_sequence; | ||
531 | - | ||
532 | /* We can fixup call to a defined non-global address | ||
533 | within the same section only. */ | ||
534 | buf[0] = INST_BYTE0 (inst1); | ||
535 | diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h | ||
536 | index bd1cc90bff6..cf5b5920921 100644 | ||
537 | --- a/opcodes/microblaze-opc.h | ||
538 | +++ b/opcodes/microblaze-opc.h | ||
539 | @@ -626,8 +626,8 @@ char pvr_register_prefix[] = "rpvr"; | ||
540 | #define MIN_IMM6_WIDTH ((int) 0x00000001) | ||
541 | #define MAX_IMM6_WIDTH ((int) 0x00000040) | ||
542 | |||
543 | -#define MIN_IMML ((long long) 0xffffff8000000000L) | ||
544 | -#define MAX_IMML ((long long) 0x0000007fffffffffL) | ||
545 | +#define MIN_IMML ((long long) -9223372036854775807) | ||
546 | +#define MAX_IMML ((long long) 9223372036854775807) | ||
547 | |||
548 | #endif /* MICROBLAZE_OPC */ | ||
549 | |||
550 | -- | ||
551 | 2.17.1 | ||
552 | |||