diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 19 | ||||
-rw-r--r-- | gas/config/tc-microblaze.c | 45 |
2 files changed, 55 insertions, 9 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index c16ea00..a12fb9e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,22 @@ +2018-04-09 Andrew Sadek <andrew.sadek.se@gmail.com> + + Microblaze Target: PIC data text relative + + * gas/config/tc-microblaze.c (Handle new relocs directives in + assembler): Handle new relocs from compiler output. + (imm_types): add new imm types for data text relative addressing + TEXT_OFFSET, TEXT_PC_OFFSET + (md_convert_frag): conversion for BFD_RELOC_MICROBLAZE_64_TEXTPCREL, + BFD_RELOC_MICROBLAZE_64_TEXTPCREL + (md_apply_fix): apply fix for BFD_RELOC_MICROBLAZE_64_TEXTPCREL, + BFD_RELOC_MICROBLAZE_64_TEXTPCREL + (md_estimate_size_before_relax): estimate size for + BFD_RELOC_MICROBLAZE_64_TEXTPCREL, + BFD_RELOC_MICROBLAZE_64_TEXTPCREL + (tc_gen_reloc): generate relocations for + BFD_RELOC_MICROBLAZE_64_TEXTPCREL, + BFD_RELOC_MICROBLAZE_64_TEXTPCREL + 2018-04-17 Igor Tsimbalist <igor.v.tsimbalist@intel.com> * testsuite/gas/i386/nops.s: Revert back deleted lines and diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c index 0194cd9..ba6eabb 100644 --- a/gas/config/tc-microblaze.c +++ b/gas/config/tc-microblaze.c @@ -87,6 +87,8 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP"; #define TLSDTPREL_OFFSET 14 #define TLSGOTTPREL_OFFSET 15 #define TLSTPREL_OFFSET 16 +#define TEXT_OFFSET 17 +#define TEXT_PC_OFFSET 18 /* Initialize the relax table. */ const relax_typeS md_relax_table[] = @@ -107,7 +109,9 @@ const relax_typeS md_relax_table[] = { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 14: TLSDTPREL_OFFSET. */ { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */ - { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */ + { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */ + { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */ + { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */ }; static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */ @@ -624,7 +628,9 @@ parse_exp (char *s, expressionS *e) #define IMM_TLSDTPMOD 6 #define IMM_TLSDTPREL 7 #define IMM_TLSTPREL 8 -#define IMM_MAX 9 +#define IMM_TXTREL 9 +#define IMM_TXTPCREL 10 +#define IMM_MAX 11 struct imm_type { const char *isuffix; /* Suffix String */ @@ -643,7 +649,9 @@ static struct imm_type imm_types[] = { { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET }, { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET }, { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET }, - { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET } + { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET }, + { "TXTREL", IMM_TXTREL, TEXT_OFFSET }, + { "TXTPCREL", IMM_TXTPCREL, TEXT_PC_OFFSET } }; static int @@ -1019,7 +1027,7 @@ md_assemble (char * str) if (check_spl_reg (& reg2)) as_fatal (_("Cannot use special register with this instruction")); - if (exp.X_op != O_constant) + if (exp.X_op != O_constant || exp.X_md == IMM_TXTPCREL) { const char *opc; relax_substateT subtype; @@ -1921,6 +1929,18 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, fragP->fr_fix += INST_WORD_SIZE * 2; fragP->fr_var = 0; break; + case TEXT_OFFSET: + fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, + fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TEXTREL); + fragP->fr_fix += INST_WORD_SIZE * 2; + fragP->fr_var = 0; + break; + case TEXT_PC_OFFSET: + fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, + fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TEXTPCREL); + fragP->fr_fix += INST_WORD_SIZE * 2; + fragP->fr_var = 0; + break; case PLT_OFFSET: fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT); @@ -2097,6 +2117,7 @@ md_apply_fix (fixS * fixP, break; case BFD_RELOC_64_PCREL: case BFD_RELOC_64: + case BFD_RELOC_MICROBLAZE_64_TEXTREL: /* Add an imm instruction. First save the current instruction. */ for (i = 0; i < INST_WORD_SIZE; i++) buf[i + INST_WORD_SIZE] = buf[i]; @@ -2144,6 +2165,7 @@ md_apply_fix (fixS * fixP, case BFD_RELOC_MICROBLAZE_64_GOT: case BFD_RELOC_MICROBLAZE_64_PLT: case BFD_RELOC_MICROBLAZE_64_GOTOFF: + case BFD_RELOC_MICROBLAZE_64_TEXTPCREL: /* Add an imm instruction. First save the current instruction. */ for (i = 0; i < INST_WORD_SIZE; i++) buf[i + INST_WORD_SIZE] = buf[i]; @@ -2240,16 +2262,18 @@ md_estimate_size_before_relax (fragS * fragP, break; case INST_NO_OFFSET: + case TEXT_OFFSET: /* Used to be a reference to somewhere which was unknown. */ if (fragP->fr_symbol) { if (fragP->fr_opcode == NULL) { - /* Used as an absolute value. */ - fragP->fr_subtype = DEFINED_ABS_SEGMENT; - /* Variable part does not change. */ - fragP->fr_var = INST_WORD_SIZE*2; - } + /* Used as an absolute value. */ + if (fragP->fr_subtype == INST_NO_OFFSET) + fragP->fr_subtype = DEFINED_ABS_SEGMENT; + /* Variable part does not change. */ + fragP->fr_var = INST_WORD_SIZE*2; + } else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor)) { /* It is accessed using the small data read only anchor. */ @@ -2318,6 +2342,7 @@ md_estimate_size_before_relax (fragS * fragP, case GOT_OFFSET: case PLT_OFFSET: case GOTOFF_OFFSET: + case TEXT_PC_OFFSET: case TLSGD_OFFSET: case TLSLD_OFFSET: case TLSTPREL_OFFSET: @@ -2418,6 +2443,8 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) case BFD_RELOC_MICROBLAZE_64_TLSDTPREL: case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL: case BFD_RELOC_MICROBLAZE_64_TLSTPREL: + case BFD_RELOC_MICROBLAZE_64_TEXTPCREL: + case BFD_RELOC_MICROBLAZE_64_TEXTREL: code = fixp->fx_r_type; break; |