From 3f0a5f17d7fe1f3d0911ad67a5993be59983fb00 Mon Sep 17 00:00:00 2001 From: Michael Eager Date: Tue, 17 Apr 2018 14:47:13 -0700 Subject: [MicroBlaze] PIC data text relative Andrew Sadek A new implemented feature in GCC Microblaze that allows Position Independent Code to run using Data Text Relative addressing instead of using Global Offset Table. Its aim was to make 'PIC' more efficient and flexible as elf size excess performance overhead were noticed when using GOT due to the indirect addressing. include/ChangeLog: * bfdlink.h (Add flag): Add new flag @ 'bfd_link_info' struct. * elf/microblaze.h (Add 3 new relocations): R_MICROBLAZE_TEXTPCREL_64, R_MICROBLAZE_TEXTREL_64 and R_MICROBLAZE_TEXTREL_32_LO for relax function. bfd/ChangeLog: * bfd/reloc.c (2 new BFD relocations): BFD_RELOC_MICROBLAZE_64_TEXTPCREL & BFD_RELOC_MICROBLAZE_64_TEXTPCREL * bfd/bfd-in2.h: Regenerate * bfd/libbfd.h: Regenerate * bfd/elf32-microblaze.c (Handle new relocs): define 'HOWTO' of 3 new relocs and handle them in both relocate and relax functions. (microblaze_elf_reloc_type_lookup): add mapping between for new bfd relocs. (microblaze_elf_relocate_section): Handle new relocs in case of elf relocation. (microblaze_elf_relax_section): Handle new relocs for elf relaxation. gas/ChangeLog: * 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 ld/ChangeLog: * ld/lexsup.c (Add 2 ld options): (ld_options): add disable-multiple-abs-defs @ 'ld_options' array (parse_args): parse new option and pass flag to 'link_info' struct. * ld/ldlex.h (Add enum): add new enum @ 'option_values' enum. * ld/ld.texinfo (Add new option): Add description for 'disable-multiple-abs-defs' * ld/main.c: Initialize flags with false @ 'main'. Handle disable-multiple-abs-defs @ 'mutiple_definition'. --- gas/ChangeLog | 19 +++++++++++++++++++ gas/config/tc-microblaze.c | 45 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 9 deletions(-) (limited to 'gas') 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 + + 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 * 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; -- cgit v1.1