blob: b98db228d1dc743433a4d938eed4dd6d4dc50152 [file] [log] [blame]
From 6b6c4a67212ced3fe1593fb173cfc4bce8d7f922 Mon Sep 17 00:00:00 2001
From: Nagaraju Mekala <nmekala@xilix.com>
Date: Tue, 11 Sep 2018 17:30:17 +0530
Subject: [PATCH] Added relocations for MB-X
Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
---
bfd/bfd-in2.h | 11 ++++--
bfd/libbfd.h | 4 +--
bfd/reloc.c | 26 +++++++-------
gas/config/tc-microblaze.c | 90 ++++++++++++++++++++--------------------------
4 files changed, 62 insertions(+), 69 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 90645d1..f74aac1 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5873,16 +5873,21 @@ done here - only used for relaxing */
BFD_RELOC_MICROBLAZE_32_NONE,
/* This is a 64 bit reloc that stores the 32 bit pc relative
- * +value in two words (with an imm instruction). No relocation is
+ * +value in two words (with an imml instruction). No relocation is
* +done here - only used for relaxing */
- BFD_RELOC_MICROBLAZE_64_NONE,
+ BFD_RELOC_MICROBLAZE_64_PCREL,
-/* This is a 64 bit reloc that stores the 32 bit pc relative
+/* This is a 64 bit reloc that stores the 32 bit relative
* +value in two words (with an imml instruction). No relocation is
* +done here - only used for relaxing */
BFD_RELOC_MICROBLAZE_64,
/* This is a 64 bit reloc that stores the 32 bit pc relative
+ * +value in two words (with an imm instruction). No relocation is
+ * +done here - only used for relaxing */
+ BFD_RELOC_MICROBLAZE_64_NONE,
+
+/* This is a 64 bit reloc that stores the 32 bit pc relative
value in two words (with an imm instruction). The relocation is
PC-relative GOT offset */
BFD_RELOC_MICROBLAZE_64_GOTPC,
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 450653f..d87a183 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2903,14 +2903,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
"BFD_RELOC_MICROBLAZE_32_NONE",
"BFD_RELOC_MICROBLAZE_64_NONE",
- "BFD_RELOC_MICROBLAZE_64",
"BFD_RELOC_MICROBLAZE_64_GOTPC",
- "BFD_RELOC_MICROBLAZE_64_GPC",
"BFD_RELOC_MICROBLAZE_64_GOT",
"BFD_RELOC_MICROBLAZE_64_PLT",
"BFD_RELOC_MICROBLAZE_64_GOTOFF",
"BFD_RELOC_MICROBLAZE_32_GOTOFF",
"BFD_RELOC_MICROBLAZE_COPY",
+ "BFD_RELOC_MICROBLAZE_64",
+ "BFD_RELOC_MICROBLAZE_64_PCREL",
"BFD_RELOC_MICROBLAZE_64_TLS",
"BFD_RELOC_MICROBLAZE_64_TLSGD",
"BFD_RELOC_MICROBLAZE_64_TLSLD",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index ccf29f5..861f2d4 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -6804,12 +6804,6 @@ ENUMDOC
ENUM
BFD_RELOC_MICROBLAZE_64_NONE
ENUMDOC
- This is a 32 bit reloc that stores the 32 bit pc relative
- value in two words (with an imml instruction). No relocation is
- done here - only used for relaxing
-ENUM
- BFD_RELOC_MICROBLAZE_64
-ENUMDOC
This is a 64 bit reloc that stores the 32 bit pc relative
value in two words (with an imm instruction). No relocation is
done here - only used for relaxing
@@ -6817,12 +6811,6 @@ ENUM
BFD_RELOC_MICROBLAZE_64_GOTPC
ENUMDOC
This is a 64 bit reloc that stores the 32 bit pc relative
- value in two words (with an imml instruction). No relocation is
- done here - only used for relaxing
-ENUM
- BFD_RELOC_MICROBLAZE_64_GPC
-ENUMDOC
- This is a 64 bit reloc that stores the 32 bit pc relative
value in two words (with an imm instruction). The relocation is
PC-relative GOT offset
ENUM
@@ -6906,6 +6894,20 @@ ENUMDOC
value in two words (with an imm instruction). The relocation is
relative offset from start of TEXT.
+ This is a 64 bit reloc that stores 64-bit thread pointer relative offset
+ to two words (uses imml instruction).
+ENUM
+BFD_RELOC_MICROBLAZE_64,
+ENUMDOC
+ This is a 64 bit reloc that stores the 64 bit pc relative
+ value in two words (with an imml instruction). No relocation is
+ done here - only used for relaxing
+ENUM
+BFD_RELOC_MICROBLAZE_64_PCREL,
+ENUMDOC
+ This is a 32 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imml instruction). No relocation is
+ done here - only used for relaxing
ENUM
BFD_RELOC_AARCH64_RELOC_START
ENUMDOC
diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
index 3f90b7c..587a4d5 100644
--- a/gas/config/tc-microblaze.c
+++ b/gas/config/tc-microblaze.c
@@ -95,6 +95,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
#define TEXT_OFFSET 17
#define TEXT_PC_OFFSET 18
#define DEFINED_64_OFFSET 19
+#define DEFINED_64_PC_OFFSET 20
/* Initialize the relax table. */
const relax_typeS md_relax_table[] =
@@ -119,7 +120,8 @@ const relax_typeS md_relax_table[] =
{ 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
{ 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
// { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
- { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 17: DEFINED_64_OFFSET. */
+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE, 0 } /* 19: DEFINED_64_OFFSET. */
+ { 0x7fffffffffffffff, 0x8000000000000000, INST_WORD_SIZE*2, 0 } /* 20: DEFINED_64_PC_OFFSET. */
};
static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
@@ -1180,33 +1182,6 @@ md_assemble (char * str)
inst |= (immed << IMM_LOW) & IMM_MASK;
}
}
-#if 0 //revisit
- else if (streq (name, "lli") || streq (name, "sli"))
- {
- temp = immed & 0xFFFFFFFFFFFF8000;
- if ((temp != 0) && (temp != 0xFFFFFFFFFFFF8000))
- {
- /* 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;
- }
-
- inst1 = opcode1->bit_sequence;
- inst1 |= ((immedl & 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;
- }
-#endif
else
{
temp = immed & 0xFFFF8000;
@@ -1958,8 +1933,8 @@ md_assemble (char * str)
if (exp.X_op != O_constant)
{
- char *opc = NULL;
- //char *opc = str_microblaze_64;
+ //char *opc = NULL;
+ char *opc = str_microblaze_64;
relax_substateT subtype;
if (exp.X_md != 0)
@@ -2221,13 +2196,19 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
fragP->fr_fix += INST_WORD_SIZE * 2;
fragP->fr_var = 0;
break;
+ case DEFINED_64_PC_OFFSET:
+ fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
+ fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PCREL);
+ fragP->fr_fix += INST_WORD_SIZE * 2;
+ fragP->fr_var = 0;
+ break;
case DEFINED_64_OFFSET:
if (fragP->fr_symbol == GOT_symbol)
fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GPC);
+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GPC);
else
fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
- fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64);
+ fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64);
fragP->fr_fix += INST_WORD_SIZE * 2;
fragP->fr_var = 0;
break;
@@ -2237,7 +2218,7 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
else
fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
- fragP->fr_offset, TRUE, BFD_RELOC_64);
+ fragP->fr_offset, FALSE, BFD_RELOC_64);
fragP->fr_fix += INST_WORD_SIZE * 2;
fragP->fr_var = 0;
break;
@@ -2457,14 +2438,17 @@ md_apply_fix (fixS * fixP,
}
}
break;
+
case BFD_RELOC_64_PCREL:
case BFD_RELOC_64:
case BFD_RELOC_MICROBLAZE_64_TEXTREL:
case BFD_RELOC_MICROBLAZE_64:
+ case BFD_RELOC_MICROBLAZE_64_PCREL:
/* Add an imm instruction. First save the current instruction. */
for (i = 0; i < INST_WORD_SIZE; i++)
buf[i + INST_WORD_SIZE] = buf[i];
- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64
+ || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
{
/* Generate the imm instruction. */
opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
@@ -2477,6 +2461,10 @@ 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;
+ 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)
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
}
else
{
@@ -2487,7 +2475,7 @@ md_apply_fix (fixS * fixP,
as_bad (_("unknown opcode \"%s\""), "imm");
return;
}
-
+
inst1 = opcode1->bit_sequence;
if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
@@ -2534,7 +2522,7 @@ md_apply_fix (fixS * fixP,
opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
if (opcode1 == NULL)
{
- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
+ if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GPC)
as_bad (_("unknown opcode \"%s\""), "imml");
else
as_bad (_("unknown opcode \"%s\""), "imm");
@@ -2561,8 +2549,6 @@ md_apply_fix (fixS * fixP,
moves code around due to relaxing. */
if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
- if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64)
- fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
else if (fixP->fx_r_type == BFD_RELOC_32)
fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
else
@@ -2613,33 +2599,24 @@ md_estimate_size_before_relax (fragS * fragP,
if(streq (fragP->fr_opcode, str_microblaze_64))
{
/* Used as an absolute value. */
- fragP->fr_subtype = DEFINED_64_OFFSET;
+ fragP->fr_subtype = DEFINED_64_PC_OFFSET;
/* Variable part does not change. */
- fragP->fr_var = INST_WORD_SIZE;
+ fragP->fr_var = INST_WORD_SIZE*2;
}
else
{
fragP->fr_subtype = DEFINED_PC_OFFSET;
- /* Don't know now whether we need an imm instruction. */
+ /* Don't know now whether we need an imm instruction. */
fragP->fr_var = INST_WORD_SIZE;
}
}
else
{
fragP->fr_subtype = DEFINED_PC_OFFSET;
- /* Don't know now whether we need an imm instruction. */
+ /* Don't know now whether we need an imm instruction. */
fragP->fr_var = INST_WORD_SIZE;
}
}
- #if 0
- else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
- !S_IS_WEAK (fragP->fr_symbol))
- {
- fragP->fr_subtype = DEFINED_PC_OFFSET;
- /* Don't know now whether we need an imm instruction. */
- fragP->fr_var = INST_WORD_SIZE;
- }
-#endif
else if (S_IS_DEFINED (fragP->fr_symbol)
&& (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
{
@@ -2669,6 +2646,13 @@ md_estimate_size_before_relax (fragS * fragP,
/* Variable part does not change. */
fragP->fr_var = INST_WORD_SIZE*2;
}
+ else if (streq (fragP->fr_opcode, str_microblaze_64))
+ {
+ /* Used as an absolute value. */
+ fragP->fr_subtype = DEFINED_64_OFFSET;
+ /* Variable part does not change. */
+ fragP->fr_var = INST_WORD_SIZE;
+ }
else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
{
/* It is accessed using the small data read only anchor. */
@@ -2743,6 +2727,7 @@ md_estimate_size_before_relax (fragS * fragP,
case TLSTPREL_OFFSET:
case TLSDTPREL_OFFSET:
case DEFINED_64_OFFSET:
+ case DEFINED_64_PC_OFFSET:
fragP->fr_var = INST_WORD_SIZE*2;
break;
case DEFINED_RO_SEGMENT:
@@ -2796,7 +2781,7 @@ md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
else
{
/* The case where we are going to resolve things... */
- if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64)
+ if (fixp->fx_r_type == BFD_RELOC_64_PCREL ||fixp->fx_r_type == BFD_RELOC_MICROBLAZE_64_PCREL)
return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
else
return fixp->fx_where + fixp->fx_frag->fr_address;
@@ -2831,6 +2816,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
case BFD_RELOC_MICROBLAZE_64_GOTPC:
case BFD_RELOC_MICROBLAZE_64_GPC:
case BFD_RELOC_MICROBLAZE_64:
+ case BFD_RELOC_MICROBLAZE_64_PCREL:
case BFD_RELOC_MICROBLAZE_64_GOT:
case BFD_RELOC_MICROBLAZE_64_PLT:
case BFD_RELOC_MICROBLAZE_64_GOTOFF: