summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools/binutils/binutils/0028-Patch-MicroBlaze-double-imml-generation-for-64-bit-v.patch
diff options
context:
space:
mode:
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.patch552
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 @@
1From 623f4e7ea6c18bec0e141c7471c7bd609bd9a6d7 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 26 Aug 2019 15:29:42 +0530
4Subject: [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
12diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
13index 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);
535diff --git a/opcodes/microblaze-opc.h b/opcodes/microblaze-opc.h
536index 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--
5512.17.1
552