/* tc-tilepro.c -- Assemble for a TILEPro chip.
- Copyright 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
MA 02110-1301, USA. */
#include "as.h"
-#include "struc-symbol.h"
#include "subsegs.h"
#include "elf/tilepro.h"
size_t md_longopts_size = sizeof (md_longopts);
int
-md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
{
switch (c)
{
/* Extra expression types. */
-#define O_lo16 O_md1
-#define O_hi16 O_md2
-#define O_ha16 O_md3
-#define O_got O_md4
+#define O_lo16 O_md1
+#define O_hi16 O_md2
+#define O_ha16 O_md3
+#define O_got O_md4
#define O_got_lo16 O_md5
#define O_got_hi16 O_md6
#define O_got_ha16 O_md7
-#define O_plt O_md8
+#define O_plt O_md8
#define O_tls_gd O_md9
#define O_tls_gd_lo16 O_md10
#define O_tls_gd_hi16 O_md11
#define O_tls_ie_lo16 O_md14
#define O_tls_ie_hi16 O_md15
#define O_tls_ie_ha16 O_md16
+#define O_tls_le O_md17
+#define O_tls_le_lo16 O_md18
+#define O_tls_le_hi16 O_md19
+#define O_tls_le_ha16 O_md20
+#define O_tls_gd_call O_md21
+#define O_tls_gd_add O_md22
+#define O_tls_ie_load O_md23
static struct hash_control *special_operator_hash;
int i;
/* Guarantee text section is aligned. */
- bfd_set_section_alignment (stdoutput, text_section,
+ bfd_set_section_alignment (text_section,
TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES);
require_canonical_reg_names = 1;
INSERT_SPECIAL_OP(tls_ie_lo16);
INSERT_SPECIAL_OP(tls_ie_hi16);
INSERT_SPECIAL_OP(tls_ie_ha16);
+ INSERT_SPECIAL_OP(tls_le);
+ INSERT_SPECIAL_OP(tls_le_lo16);
+ INSERT_SPECIAL_OP(tls_le_hi16);
+ INSERT_SPECIAL_OP(tls_le_ha16);
+ INSERT_SPECIAL_OP(tls_gd_call);
+ INSERT_SPECIAL_OP(tls_gd_add);
+ INSERT_SPECIAL_OP(tls_ie_load);
#undef INSERT_SPECIAL_OP
/* Initialize op_hash hash table. */
insert_operand (tilepro_bundle_bits bits,
const struct tilepro_operand *operand,
int operand_value,
- char *file,
+ const char *file,
unsigned lineno)
{
/* Range-check the immediate. */
switch (op)
{
case O_lo16:
- case O_got:
- case O_got_lo16:
- case O_tls_gd:
- case O_tls_gd_lo16:
- case O_tls_ie:
- case O_tls_ie_lo16:
return (signed short)num;
case O_hi16:
- case O_got_hi16:
- case O_tls_gd_hi16:
- case O_tls_ie_hi16:
return (signed short)(num >> 16);
case O_ha16:
- case O_got_ha16:
- case O_tls_gd_ha16:
- case O_tls_ie_ha16:
return (signed short)((num + 0x8000) >> 16);
default:
require_symbol = 1;
break;
+ case O_tls_le:
+ HANDLE_OP16 (TLS_LE);
+ require_symbol = 1;
+ break;
+
+ case O_tls_le_lo16:
+ HANDLE_OP16 (TLS_LE_LO);
+ require_symbol = 1;
+ break;
+
+ case O_tls_le_hi16:
+ HANDLE_OP16 (TLS_LE_HI);
+ require_symbol = 1;
+ break;
+
+ case O_tls_le_ha16:
+ HANDLE_OP16 (TLS_LE_HA);
+ require_symbol = 1;
+ break;
+
#undef HANDLE_OP16
case O_plt:
require_symbol = 1;
break;
+ case O_tls_gd_call:
+ switch (reloc)
+ {
+ case BFD_RELOC_TILEPRO_JOFFLONG_X1:
+ reloc = BFD_RELOC_TILEPRO_TLS_GD_CALL;
+ break;
+ default:
+ die = 1;
+ break;
+ }
+ use_subexp = 1;
+ require_symbol = 1;
+ break;
+
+ case O_tls_gd_add:
+ switch (reloc)
+ {
+ case BFD_RELOC_TILEPRO_IMM8_X0:
+ reloc = BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD;
+ break;
+ case BFD_RELOC_TILEPRO_IMM8_X1:
+ reloc = BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD;
+ break;
+ case BFD_RELOC_TILEPRO_IMM8_Y0:
+ reloc = BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD;
+ break;
+ case BFD_RELOC_TILEPRO_IMM8_Y1:
+ reloc = BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD;
+ break;
+ default:
+ die = 1;
+ break;
+ }
+ use_subexp = 1;
+ require_symbol = 1;
+ break;
+
+ case O_tls_ie_load:
+ switch (reloc)
+ {
+ case BFD_RELOC_TILEPRO_IMM8_X1:
+ reloc = BFD_RELOC_TILEPRO_TLS_IE_LOAD;
+ break;
+ default:
+ die = 1;
+ break;
+ }
+ use_subexp = 1;
+ require_symbol = 1;
+ break;
+
default:
/* Do nothing. */
break;
}
else if (use_subexp)
{
+ expressionS *sval = NULL;
/* Now that we've changed the reloc, change ha16(x) into x,
etc. */
- if (operand_exp->X_add_symbol->sy_value.X_md)
+ if (symbol_symbolS (operand_exp->X_add_symbol))
+ sval = symbol_get_value_expression (operand_exp->X_add_symbol);
+ if (sval && sval->X_md)
{
/* HACK: We used X_md to mark this symbol as a fake wrapper
around a real expression. To unwrap it, we just grab its
value here. */
- operand_exp = &operand_exp->X_add_symbol->sy_value;
+ operand_exp = sval;
if (require_symbol)
{
/* If the section seems to have no alignment set yet, go ahead and
make it large enough to hold code. */
- if (bfd_get_section_alignment (stdoutput, now_seg) == 0)
- bfd_set_section_alignment (stdoutput, now_seg,
+ if (bfd_section_alignment (now_seg) == 0)
+ bfd_set_section_alignment (now_seg,
TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES);
for (j = 0; j < current_bundle_index; j++)
/* HACK: mark this symbol as a temporary wrapper around a proper
expression, so we can unwrap it later once we have communicated
the relocation type. */
- sym->sy_value.X_md = 1;
+ symbol_get_value_expression (sym)->X_md = 1;
}
memset (e, 0, sizeof *e);
/* Zero everything to make sure we don't miss any flags. */
memset (expression, 0, sizeof *expression);
- char* regname = input_line_pointer;
- char terminating_char = get_symbol_end ();
+ char *regname;
+ char terminating_char = get_symbol_name (®name);
void* pval = hash_find (main_reg_hash, regname);
regname, tilepro_register_names[regno]);
/* Restore the old character following the register name. */
- *input_line_pointer = terminating_char;
+ (void) restore_line_pointer (terminating_char);
/* Fill in the expression fields to indicate it's a register. */
expression->X_op = O_register;
{ NULL, 0, 0 }
};
-/* Equal to MAX_PRECISION in atof-ieee.c */
-#define MAX_LITTLENUMS 6
-
/* Turn the string pointed to by litP into a floating point constant
of type TYPE, and emit the appropriate bytes. The number of
LITTLENUMS emitted is stored in *SIZEP. An error message is
returned, or NULL on OK. */
-char *
+const char *
md_atof (int type, char *litP, int *sizeP)
{
int prec;
#ifdef OBJ_ELF
switch (fixP->fx_r_type)
{
+ case BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD:
+ case BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD:
+ case BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD:
+ case BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD:
case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD:
case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD:
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE:
case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO:
case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO:
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO:
case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI:
case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI:
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI:
case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA:
case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA:
+ case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE:
+ case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE:
+ case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO:
+ case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO:
+ case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI:
+ case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI:
case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA:
case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA:
+ case BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE:
+ case BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE:
+ case BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO:
+ case BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO:
+ case BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI:
+ case BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI:
+ case BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA:
+ case BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA:
+ case BFD_RELOC_TILEPRO_TLS_GD_CALL:
+ case BFD_RELOC_TILEPRO_TLS_IE_LOAD:
case BFD_RELOC_TILEPRO_TLS_DTPMOD32:
case BFD_RELOC_TILEPRO_TLS_DTPOFF32:
case BFD_RELOC_TILEPRO_TLS_TPOFF32:
/* Apply lo16, hi16, ha16, etc. munging. */
switch (fixP->fx_r_type)
{
- case BFD_RELOC_TILEPRO_IMM16_X0_GOT:
- case BFD_RELOC_TILEPRO_IMM16_X1_GOT:
- *valP = value = apply_special_operator (O_got, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO:
- case BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO:
- *valP = value = apply_special_operator (O_got_lo16, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI:
- case BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI:
- *valP = value = apply_special_operator (O_got_hi16, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA:
- case BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA:
- *valP = value = apply_special_operator (O_got_ha16, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD:
- *valP = value = apply_special_operator (O_tls_gd, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE:
- *valP = value = apply_special_operator (O_tls_ie, value);
- break;
-
case BFD_RELOC_LO16:
case BFD_RELOC_TILEPRO_IMM16_X0_LO:
case BFD_RELOC_TILEPRO_IMM16_X1_LO:
*valP = value = apply_special_operator (O_lo16, value);
break;
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO:
- *valP = value = apply_special_operator (O_tls_gd_lo16, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO:
- *valP = value = apply_special_operator (O_tls_ie_lo16, value);
- break;
-
case BFD_RELOC_HI16:
case BFD_RELOC_TILEPRO_IMM16_X0_HI:
case BFD_RELOC_TILEPRO_IMM16_X1_HI:
*valP = value = apply_special_operator (O_hi16, value);
break;
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI:
- *valP = value = apply_special_operator (O_tls_gd_hi16, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI:
- *valP = value = apply_special_operator (O_tls_ie_hi16, value);
- break;
-
case BFD_RELOC_HI16_S:
case BFD_RELOC_TILEPRO_IMM16_X0_HA:
case BFD_RELOC_TILEPRO_IMM16_X1_HA:
*valP = value = apply_special_operator (O_ha16, value);
break;
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA:
- *valP = value = apply_special_operator (O_tls_gd_ha16, value);
- break;
-
- case BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA:
- case BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA:
- *valP = value = apply_special_operator (O_tls_ie_ha16, value);
- break;
-
default:
/* Do nothing */
break;
{
arelent *reloc;
- reloc = (arelent *) xmalloc (sizeof (arelent));
- reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ reloc = XNEW (arelent);
+ reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;