/* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
- Copyright (C) 2009-2018 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#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[] =
{ 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. */
microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
{
#ifdef OBJ_ELF
- obj_elf_change_section (".data", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE,
+ obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE,
0, 0, 0, 0);
#else
s_data (ignore);
microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
{
#ifdef OBJ_ELF
- obj_elf_change_section (".sdata", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE,
+ obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE,
0, 0, 0, 0);
#else
s_data (ignore);
if (localvar == 0)
{
/* rodata. */
- obj_elf_change_section (".rodata", SHT_PROGBITS, 0, SHF_ALLOC,
+ obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC,
0, 0, 0, 0);
if (rodata_segment == 0)
rodata_segment = subseg_new (".rodata", 0);
else
{
/* 1 .sdata2. */
- obj_elf_change_section (".sdata2", SHT_PROGBITS, 0, SHF_ALLOC,
+ obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC,
0, 0, 0, 0);
}
#else
{
#ifdef OBJ_ELF
if (localvar == 0) /* bss. */
- obj_elf_change_section (".bss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE,
+ obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE,
0, 0, 0, 0);
else if (localvar == 1)
{
/* sbss. */
- obj_elf_change_section (".sbss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE,
+ obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE,
0, 0, 0, 0);
if (sbss_segment == 0)
sbss_segment = subseg_new (".sbss", 0);
#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 */
{ "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
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;
return NULL;
}
-/* Various routines to kill one day. */
-/* Equal to MAX_PRECISION in atof-ieee.c */
-#define MAX_LITTLENUMS 6
-
/* Turn a string in input_line_pointer into a floating point constant of type
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
+
const char *
md_atof (int type, char * litP, int * sizeP)
{
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);
valueT * valp,
segT segment)
{
- char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ char * buf = fixP->fx_where + &fixP->fx_frag->fr_literal[0];
const char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
const char * symname;
/* Note: use offsetT because it is signed, valueT is unsigned. */
{
if (S_IS_WEAK (fixP->fx_addsy)
|| (symbol_used_in_reloc_p (fixP->fx_addsy)
- && (((bfd_get_section_flags (stdoutput,
- S_GET_SEGMENT (fixP->fx_addsy))
+ && (((bfd_section_flags (S_GET_SEGMENT (fixP->fx_addsy))
& SEC_LINK_ONCE) != 0)
|| !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
".gnu.linkonce",
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];
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];
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. */
case GOT_OFFSET:
case PLT_OFFSET:
case GOTOFF_OFFSET:
+ case TEXT_PC_OFFSET:
case TLSGD_OFFSET:
case TLSLD_OFFSET:
case TLSTPREL_OFFSET:
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;