aboutsummaryrefslogtreecommitdiffstats
path: root/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch')
-rw-r--r--meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch375
1 files changed, 375 insertions, 0 deletions
diff --git a/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch
new file mode 100644
index 00000000..814672d2
--- /dev/null
+++ b/meta-xilinx-bsp/recipes-microblaze/binutils/binutils-2.31/0019-Fixed-MB-x-relocation-issues.patch
@@ -0,0 +1,375 @@
+From b63b8ae83cc538808e06d84143df6b7150fb4037 Mon Sep 17 00:00:00 2001
+From: Nagaraju Mekala <nmekala@xilix.com>
+Date: Fri, 28 Sep 2018 12:04:55 +0530
+Subject: [PATCH 19/31] -Fixed MB-x relocation issues -Added imml for required
+ MB-x instructions
+
+Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
+Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
+---
+ bfd/elf64-microblaze.c | 68 ++++++++++++++++----
+ gas/config/tc-microblaze.c | 152 ++++++++++++++++++++++++++++++++-------------
+ gas/tc.h | 2 +-
+ 3 files changed, 167 insertions(+), 55 deletions(-)
+
+diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
+index 56a45f2..54a2461 100644
+--- a/bfd/elf64-microblaze.c
++++ b/bfd/elf64-microblaze.c
+@@ -1476,8 +1476,17 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+- bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
++ if (insn == 0xb2000000 || insn == 0xb2ffffff)
++ {
++ insn &= ~0x00ffffff;
++ insn |= (relocation >> 16) & 0xffffff;
++ bfd_put_32 (input_bfd, insn,
+ contents + offset + endian);
++ }
++ else
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+@@ -1567,11 +1576,28 @@ microblaze_elf_relocate_section (bfd *output_bfd,
+ else
+ {
+ if (r_type == R_MICROBLAZE_64_PCREL)
+- relocation -= (input_section->output_section->vma
+- + input_section->output_offset
+- + offset + INST_WORD_SIZE);
+- bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ {
++ if (!input_section->output_section->vma &&
++ !input_section->output_offset && !offset)
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset);
++ else
++ relocation -= (input_section->output_section->vma
++ + input_section->output_offset
++ + offset + INST_WORD_SIZE);
++ }
++ unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
++ if (insn == 0xb2000000 || insn == 0xb2ffffff)
++ {
++ insn &= ~0x00ffffff;
++ insn |= (relocation >> 16) & 0xffffff;
++ bfd_put_32 (input_bfd, insn,
+ contents + offset + endian);
++ }
++ else
++ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
++ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+@@ -1690,9 +1716,19 @@ static void
+ microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
+ {
+ unsigned long instr = bfd_get_32 (abfd, bfd_addr);
+- instr &= ~0x0000ffff;
+- instr |= (val & 0x0000ffff);
+- bfd_put_32 (abfd, instr, bfd_addr);
++
++ if (instr == 0xb2000000 || instr == 0xb2ffffff)
++ {
++ instr &= ~0x00ffffff;
++ instr |= (val & 0xffffff);
++ bfd_put_32 (abfd, instr, bfd_addr);
++ }
++ else
++ {
++ instr &= ~0x0000ffff;
++ instr |= (val & 0x0000ffff);
++ bfd_put_32 (abfd, instr, bfd_addr);
++ }
+ }
+
+ /* Read-modify-write into the bfd, an immediate value into appropriate fields of
+@@ -1704,10 +1740,18 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
+ unsigned long instr_lo;
+
+ instr_hi = bfd_get_32 (abfd, bfd_addr);
+- instr_hi &= ~0x0000ffff;
+- instr_hi |= ((val >> 16) & 0x0000ffff);
+- bfd_put_32 (abfd, instr_hi, bfd_addr);
+-
++ if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff)
++ {
++ instr_hi &= ~0x00ffffff;
++ instr_hi |= (val >> 16) & 0xffffff;
++ bfd_put_32 (abfd, instr_hi,bfd_addr);
++ }
++ else
++ {
++ instr_hi &= ~0x0000ffff;
++ instr_hi |= ((val >> 16) & 0x0000ffff);
++ bfd_put_32 (abfd, instr_hi, bfd_addr);
++ }
+ instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
+ instr_lo &= ~0x0000ffff;
+ instr_lo |= (val & 0x0000ffff);
+diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
+index 663e1a6..8d2980a 100644
+--- a/gas/config/tc-microblaze.c
++++ b/gas/config/tc-microblaze.c
+@@ -392,7 +392,7 @@ microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
+ Integer arg to pass to the function. */
+ /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
+ and then in the read.c table. */
+-const pseudo_typeS md_pseudo_table[] =
++pseudo_typeS md_pseudo_table[] =
+ {
+ {"lcomm", microblaze_s_lcomm, 1},
+ {"data", microblaze_s_data, 0},
+@@ -401,7 +401,7 @@ const pseudo_typeS md_pseudo_table[] =
+ {"data32", cons, 4}, /* Same as word. */
+ {"ent", s_func, 0}, /* Treat ent as function entry point. */
+ {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
+- {"gpword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
++ {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
+ {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */
+ {"weakext", microblaze_s_weakext, 0},
+ {"rodata", microblaze_s_rdata, 0},
+@@ -996,7 +996,7 @@ md_assemble (char * str)
+ unsigned reg2;
+ unsigned reg3;
+ unsigned isize;
+- unsigned int immed, immed2, temp;
++ unsigned long immed, immed2, temp;
+ expressionS exp;
+ char name[20];
+ long immedl;
+@@ -1118,8 +1118,9 @@ md_assemble (char * str)
+ as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
+ else if (streq (name, "smi"))
+ as_fatal (_("smi pseudo instruction should not use a label in imm field"));
+-
+- if (reg2 == REG_ROSDP)
++ if(streq (name, "lli") || streq (name, "sli"))
++ opc = str_microblaze_64;
++ else if (reg2 == REG_ROSDP)
+ opc = str_microblaze_ro_anchor;
+ else if (reg2 == REG_RWSDP)
+ opc = str_microblaze_rw_anchor;
+@@ -1182,31 +1183,55 @@ md_assemble (char * str)
+ inst |= (immed << IMM_LOW) & IMM_MASK;
+ }
+ }
+- else
+- {
+- temp = immed & 0xFFFF8000;
+- if ((temp != 0) && (temp != 0xFFFF8000))
+- {
++ else if (streq (name, "lli") || streq (name, "sli"))
++ {
++ temp = immed & 0xFFFFFF8000;
++ if (temp != 0 && temp != 0xFFFFFF8000)
++ {
+ /* Needs an immediate inst. */
+- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
+ if (opcode1 == NULL)
+ {
+- as_bad (_("unknown opcode \"%s\""), "imm");
++ as_bad (_("unknown opcode \"%s\""), "imml");
+ return;
+ }
+-
+ inst1 = opcode1->bit_sequence;
+- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
++ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
+ output[0] = INST_BYTE0 (inst1);
+ output[1] = INST_BYTE1 (inst1);
+ output[2] = INST_BYTE2 (inst1);
+ output[3] = INST_BYTE3 (inst1);
+ output = frag_more (isize);
+- }
+- inst |= (reg1 << RD_LOW) & RD_MASK;
+- inst |= (reg2 << RA_LOW) & RA_MASK;
+- inst |= (immed << IMM_LOW) & IMM_MASK;
+- }
++ }
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (reg2 << RA_LOW) & RA_MASK;
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
++ else
++ {
++ temp = immed & 0xFFFF8000;
++ if ((temp != 0) && (temp != 0xFFFF8000))
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imm");
++ return;
++ }
++
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++ inst |= (reg1 << RD_LOW) & RD_MASK;
++ inst |= (reg2 << RA_LOW) & RA_MASK;
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
+ break;
+
+ case INST_TYPE_RD_R1_IMMS:
+@@ -1832,12 +1857,20 @@ md_assemble (char * str)
+ case INST_TYPE_IMM:
+ if (streq (name, "imm"))
+ as_fatal (_("An IMM instruction should not be present in the .s file"));
+-
+- op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
++ if (microblaze_arch_size == 64)
++ op_end = parse_imml (op_end + 1, & exp, MIN_IMML, MAX_IMML);
++ else
++ op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
+
+ if (exp.X_op != O_constant)
+ {
+- char *opc = NULL;
++ char *opc;
++ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
++ streq (name, "breaid") ||
++ streq (name, "brai") || streq (name, "braid")))
++ opc = str_microblaze_64;
++ else
++ opc = NULL;
+ relax_substateT subtype;
+
+ if (exp.X_md != 0)
+@@ -1860,27 +1893,54 @@ md_assemble (char * str)
+ immed = exp.X_add_number;
+ }
+
++ if (microblaze_arch_size == 64 && (streq (name, "breai") ||
++ streq (name, "breaid") ||
++ streq (name, "brai") || streq (name, "braid")))
++ {
++ temp = immed & 0xFFFFFF8000;
++ if (temp != 0)
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imml");
++ return;
++ }
+
+- temp = immed & 0xFFFF8000;
+- if ((temp != 0) && (temp != 0xFFFF8000))
+- {
+- /* Needs an immediate inst. */
+- opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
+- if (opcode1 == NULL)
+- {
+- as_bad (_("unknown opcode \"%s\""), "imm");
+- return;
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
+ }
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
++ else
++ {
++ temp = immed & 0xFFFF8000;
++ if ((temp != 0) && (temp != 0xFFFF8000))
++ {
++ /* Needs an immediate inst. */
++ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
++ if (opcode1 == NULL)
++ {
++ as_bad (_("unknown opcode \"%s\""), "imm");
++ return;
++ }
+
+- inst1 = opcode1->bit_sequence;
+- inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
+- output[0] = INST_BYTE0 (inst1);
+- output[1] = INST_BYTE1 (inst1);
+- output[2] = INST_BYTE2 (inst1);
+- output[3] = INST_BYTE3 (inst1);
+- output = frag_more (isize);
+- }
+- inst |= (immed << IMM_LOW) & IMM_MASK;
++ inst1 = opcode1->bit_sequence;
++ inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
++ output[0] = INST_BYTE0 (inst1);
++ output[1] = INST_BYTE1 (inst1);
++ output[2] = INST_BYTE2 (inst1);
++ output[3] = INST_BYTE3 (inst1);
++ output = frag_more (isize);
++ }
++ inst |= (immed << IMM_LOW) & IMM_MASK;
++ }
+ break;
+
+ case INST_TYPE_NONE:
+@@ -2460,7 +2520,7 @@ md_apply_fix (fixS * fixP,
+
+ inst1 = opcode1->bit_sequence;
+ if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
+- inst1 |= ((val & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
++ inst1 |= ((val & 0xFFFFFF0000L) >> 16) & IMML_MASK;
+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
+ fixP->fx_r_type = BFD_RELOC_64;
+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
+@@ -2628,7 +2688,14 @@ md_estimate_size_before_relax (fragS * fragP,
+ }
+ else
+ {
+- fragP->fr_subtype = UNDEFINED_PC_OFFSET;
++ if (fragP->fr_opcode != NULL) {
++ if (streq (fragP->fr_opcode, str_microblaze_64))
++ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
++ else
++ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
++ }
++ else
++ fragP->fr_subtype = UNDEFINED_PC_OFFSET;
+ fragP->fr_var = INST_WORD_SIZE*2;
+ }
+ break;
+@@ -2905,6 +2972,7 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
+ case OPTION_M64:
+ //if (arg != NULL && strcmp (arg, "64") == 0)
+ microblaze_arch_size = 64;
++ md_pseudo_table[7].poc_val = 8;
+ break;
+ default:
+ return 0;
+diff --git a/gas/tc.h b/gas/tc.h
+index beddb48..96c7559 100644
+--- a/gas/tc.h
++++ b/gas/tc.h
+@@ -22,7 +22,7 @@
+ /* In theory (mine, at least!) the machine dependent part of the assembler
+ should only have to include one file. This one. -- JF */
+
+-extern const pseudo_typeS md_pseudo_table[];
++extern pseudo_typeS md_pseudo_table[];
+
+ const char * md_atof (int, char *, int *);
+ int md_parse_option (int, const char *);
+--
+2.7.4
+