/* tc-score7.c -- Assembler for Score7
- Copyright 2009, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 Free Software Foundation, Inc.
Contributed by:
Brain.lin (brain.lin@sunplusct.com)
Mei Ligang (ligang@sunnorth.com.cn)
#include "subsegs.h"
#include "safe-ctype.h"
#include "opcode/score-inst.h"
-#include "struc-symbol.h"
#include "libiberty.h"
#ifdef OBJ_ELF
#define s7_GET_INSN_SIZE(type) ((s7_GET_INSN_CLASS (type) == INSN_CLASS_16) \
? s7_INSN16_SIZE : s7_INSN_SIZE)
-#define s7_MAX_LITTLENUMS 6
#define s7_INSN_NAME_LEN 16
/* Relax will need some padding for alignment. */
struct s7_insn_to_dependency
{
- char *insn_name;
+ const char *insn_name;
enum s7_insn_type_for_dependency type;
};
{"mvpl", s7_D_cond_mv},
{"mvvs", s7_D_cond_mv},
{"mvvc", s7_D_cond_mv},
- /* move spectial instruction. */
+ /* move special instruction. */
{"mtcr", s7_D_mtcr},
{"mftlb", s7_D_mftlb},
{"mtptlb", s7_D_mtptlb},
{s7_D_mtcr, "cr1", s7_D_pce, "", 2, 1, 0},
{s7_D_mtcr, "cr1", s7_D_cond_br, "", 1, 0, 1},
{s7_D_mtcr, "cr1", s7_D_cond_mv, "", 1, 0, 1},
- /* Status regiser. */
+ /* Status register. */
{s7_D_mtcr, "cr0", s7_D_all_insn, "", 5, 4, 0},
- /* CCR regiser. */
+ /* CCR register. */
{s7_D_mtcr, "cr4", s7_D_all_insn, "", 6, 5, 0},
/* EntryHi/EntryLo register. */
{s7_D_mftlb, "", s7_D_mtptlb, "", 1, 1, 1},
{
const struct s7_reg_entry *names;
int max_regno;
- struct hash_control *htab;
+ htab_t htab;
const char *expected;
};
{s7_score_crn_table, 31, NULL, N_("S+core co-processor register expected")},
};
-static struct hash_control *s7_score_ops_hsh = NULL;
-static struct hash_control *s7_dependency_insn_hsh = NULL;
+static htab_t s7_score_ops_hsh = NULL;
+static htab_t s7_dependency_insn_hsh = NULL;
\f
struct s7_datafield_range
}
static int
-s7_score_reg_parse (char **ccp, struct hash_control *htab)
+s7_score_reg_parse (char **ccp, htab_t htab)
{
char *start = *ccp;
char c;
c = *p++;
*--p = 0;
- reg = (struct s7_reg_entry *) hash_find (htab, start);
+ reg = (struct s7_reg_entry *) str_hash_find (htab, start);
*p = c;
if (reg)
const struct s7_insn_to_dependency *tmp;
strcpy (name, insn_name);
- tmp = (const struct s7_insn_to_dependency *) hash_find (s7_dependency_insn_hsh, name);
+ tmp = (const struct s7_insn_to_dependency *) str_hash_find (s7_dependency_insn_hsh, name);
if (tmp)
return tmp->type;
if (remainder_bubbles <= 2)
{
if (s7_warn_fix_data_dependency)
- as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
+ as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
s7_dependency_vector[i].name, s7_dependency_vector[i].reg,
s7_dependency_vector[0].name, s7_dependency_vector[0].reg,
remainder_bubbles, bubbles);
else
{
if (s7_warn_fix_data_dependency)
- as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
+ as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
s7_dependency_vector[i].name, s7_dependency_vector[i].reg,
s7_dependency_vector[0].name, s7_dependency_vector[0].reg,
bubbles);
{
if (warn_or_error)
{
- as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
+ as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
s7_dependency_vector[i].name, s7_dependency_vector[i].reg,
s7_dependency_vector[0].name, s7_dependency_vector[0].reg,
remainder_bubbles, bubbles);
}
else
{
- as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
+ as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
s7_dependency_vector[i].name, s7_dependency_vector[i].reg,
s7_dependency_vector[0].name, s7_dependency_vector[0].reg,
remainder_bubbles, bubbles);
/* Here, we must call frag_grow in order to keep the instruction frag type is
rs_machine_dependent.
For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
- acturally will call frag_wane.
+ actually will call frag_wane.
Calling frag_grow first will create a new frag_now which free size is 20 that is enough
for frag_var. */
frag_grow (20);
c = *p;
*p = '\0';
- opcode = (const struct s7_asm_opcode *) hash_find (s7_score_ops_hsh, operator);
+ opcode = (const struct s7_asm_opcode *) str_hash_find (s7_score_ops_hsh, operator);
*p = c;
memset (&s7_inst, '\0', sizeof (s7_inst));
- sprintf (s7_inst.str, "%s", insnstr);
+ strcpy (s7_inst.str, insnstr);
if (opcode)
{
s7_inst.instruction = opcode->value;
s7_inst.size = s7_GET_INSN_SIZE (s7_inst.type);
s7_inst.relax_size = 0;
s7_inst.bwarn = 0;
- sprintf (s7_inst.name, "%s", opcode->template_name);
+ strcpy (s7_inst.name, opcode->template_name);
strcpy (s7_inst.reg, "");
s7_inst.error = NULL;
s7_inst.reloc.type = BFD_RELOC_NONE;
/* Fix part
For an external symbol: lw rD, <sym>($gp)
(BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
- sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
+ sprintf (tmp, "lw_pic r%d, %s", reg_rd, S_GET_NAME (add_symbol));
if (s7_append_insn (tmp, FALSE) == (int) s7_FAIL)
return;
addi rD, <sym> (BFD_RELOC_GOT_LO16) */
s7_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
memcpy (&var_insts[0], &s7_inst, sizeof (struct s7_score_it));
- sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
+ sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, S_GET_NAME (add_symbol));
if (s7_append_insn (tmp, FALSE) == (int) s7_FAIL)
return;
else if (add_number >= -0x8000 && add_number <= 0x7fff)
{
/* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
- sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
+ sprintf (tmp, "lw_pic r%d, %s", reg_rd, S_GET_NAME (add_symbol));
if (s7_append_insn (tmp, TRUE) == (int) s7_FAIL)
return;
/* Var part
For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
- sprintf (tmp, "addi_s_pic r%d, %s + %d", reg_rd, add_symbol->bsym->name, (int) add_number);
+ sprintf (tmp, "addi_s_pic r%d, %s + %d", reg_rd,
+ S_GET_NAME (add_symbol), (int) add_number);
if (s7_append_insn (tmp, FALSE) == (int) s7_FAIL)
return;
int lo = add_number & 0x0000FFFF;
/* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
- sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
+ sprintf (tmp, "lw_pic r%d, %s", reg_rd, S_GET_NAME (add_symbol));
if (s7_append_insn (tmp, TRUE) == (int) s7_FAIL)
return;
/* Var part
For a local symbol: ldis r1, HI%<constant>
- but, if lo is outof 16 bit, make hi plus 1 */
+ but, if lo is out of 16 bit, make hi plus 1 */
if ((lo < -0x8000) || (lo > 0x7fff))
{
hi += 1;
/* Var part
For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
- sprintf (tmp, "addi_u_pic r1, %s + %d", add_symbol->bsym->name, lo);
+ sprintf (tmp, "addi_u_pic r1, %s + %d", S_GET_NAME (add_symbol), lo);
if (s7_append_insn (tmp, FALSE) == (int) s7_FAIL)
return;
/* Fix part
For an external symbol: lw rD, <sym>($gp)
(BFD_RELOC_SCORE_GOT15) */
- sprintf (tmp, "lw_pic r1, %s", add_symbol->bsym->name);
+ sprintf (tmp, "lw_pic r1, %s", S_GET_NAME (add_symbol));
if (s7_append_insn (tmp, FALSE) == (int) s7_FAIL)
return;
addi rD, <sym> (BFD_RELOC_GOT_LO16) */
s7_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
memcpy (&var_insts[0], &s7_inst, sizeof (struct s7_score_it));
- sprintf (tmp, "addi_s_pic r1, %s", add_symbol->bsym->name);
+ sprintf (tmp, "addi_s_pic r1, %s", S_GET_NAME (add_symbol));
if (s7_append_insn (tmp, FALSE) == (int) s7_FAIL)
return;
for (i = 0; i < sizeof (s7_score_insns) / sizeof (struct s7_asm_opcode); i++)
{
const struct s7_asm_opcode *insn = s7_score_insns + i;
- unsigned len = strlen (insn->template_name);
+ size_t len = strlen (insn->template_name);
struct s7_asm_opcode *new_opcode;
char *template_name;
new_opcode = (struct s7_asm_opcode *)
new_opcode->relax_value = insn->relax_value;
new_opcode->type = insn->type;
new_opcode->bitmask = insn->bitmask;
- hash_insert (s7_score_ops_hsh, new_opcode->template_name,
+ str_hash_insert (s7_score_ops_hsh, new_opcode->template_name,
(void *) new_opcode);
}
}
for (i = 0; i < ARRAY_SIZE (s7_insn_to_dependency_table); i++)
{
const struct s7_insn_to_dependency *tmp = s7_insn_to_dependency_table + i;
- unsigned len = strlen (tmp->insn_name);
+ size_t len = strlen (tmp->insn_name);
struct s7_insn_to_dependency *new_i2d;
+ char *insn_name;
new_i2d = (struct s7_insn_to_dependency *)
obstack_alloc (&dependency_obstack,
sizeof (struct s7_insn_to_dependency));
- new_i2d->insn_name = (char *) obstack_alloc (&dependency_obstack,
- len + 1);
+ insn_name = (char *) obstack_alloc (&dependency_obstack, len + 1);
- strcpy (new_i2d->insn_name, tmp->insn_name);
+ strcpy (insn_name, tmp->insn_name);
+ new_i2d->insn_name = insn_name;
new_i2d->type = tmp->type;
- hash_insert (s7_dependency_insn_hsh, new_i2d->insn_name,
+ str_hash_insert (s7_dependency_insn_hsh, new_i2d->insn_name,
(void *) new_i2d);
}
}
linkonce = FALSE;
if (symsec != segtype && ! S_IS_LOCAL (sym))
{
- if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) != 0)
+ if ((bfd_section_flags (symsec) & SEC_LINK_ONCE) != 0)
linkonce = TRUE;
/* The GNU toolchain uses an extension for ELF: a section
}
/* This must duplicate the test in adjust_reloc_syms. */
- return (symsec != &bfd_und_section
- && symsec != &bfd_abs_section
- && ! bfd_is_com_section (symsec)
- && !linkonce
+ return (!bfd_is_und_section (symsec)
+ && !bfd_is_abs_section (symsec)
+ && !bfd_is_com_section (symsec)
+ && !linkonce
#ifdef OBJ_ELF
/* A global or weak symbol is treated as external. */
&& (OUTPUT_FLAVOR != bfd_target_elf_flavour
if (change == 1)
{
/* Only at the first time determining whether s7_GP instruction relax should be done,
- return the difference between insntruction size and instruction relax size. */
+ return the difference between instruction size and instruction relax size. */
if (fragp->fr_opcode == NULL)
{
fragp->fr_fix = s7_RELAX_NEW (fragp->fr_subtype);
if (s == NULL)
frag_addr = 0;
else
- {
- if (s->bsym != 0)
- symbol_address = (addressT) s->sy_frag->fr_address;
- }
+ symbol_address = (addressT) symbol_get_frag (s)->fr_address;
value = s7_md_chars_to_number (fragp->fr_literal, s7_INSN_SIZE);
abs_value = 0xffffffff - abs_value + 1;
/* Relax branch 32 to branch 16. */
- if (relaxable_p && (s->bsym != NULL) && ((abs_value & 0xffffff00) == 0)
+ if (relaxable_p && ((abs_value & 0xffffff00) == 0)
&& (S_IS_DEFINED (s) && !S_IS_COMMON (s) && !S_IS_EXTERNAL (s)))
{
/* do nothing. */
p = strstr (insnstr, "||");
c = *p;
*p = '\0';
- sprintf (first, "%s", insnstr);
+ strcpy (first, insnstr);
/* Get second part string of PCE. */
*p = c;
p += 2;
- sprintf (second, "%s", p);
+ strcpy (second, p);
s7_parse_16_32_inst (first, FALSE);
if (s7_inst.error)
|| ((pec_part_1.size == s7_INSN16_SIZE) && (s7_inst.size == s7_INSN_SIZE)))
{
s7_inst.error = _("pce instruction error (16 bit || 16 bit)'");
- sprintf (s7_inst.str, insnstr);
+ strcpy (s7_inst.str, insnstr);
return;
}
\f
static void
-s7_insert_reg (const struct s7_reg_entry *r, struct hash_control *htab)
+s7_insert_reg (const struct s7_reg_entry *r, htab_t htab)
{
int i = 0;
int len = strlen (r->name) + 2;
- char *buf = xmalloc (len);
- char *buf2 = xmalloc (len);
+ char *buf = XNEWVEC (char, len);
+ char *buf2 = XNEWVEC (char, len);
strcpy (buf + i, r->name);
for (i = 0; buf[i]; i++)
}
buf2[i] = '\0';
- hash_insert (htab, buf, (void *) r);
- hash_insert (htab, buf2, (void *) r);
+ str_hash_insert (htab, buf, (void *) r);
+ str_hash_insert (htab, buf2, (void *) r);
}
static void
{
const struct s7_reg_entry *r;
- if ((map->htab = hash_new ()) == NULL)
+ if ((map->htab = str_htab_create ()) == NULL)
{
as_fatal (_("virtual memory exhausted"));
}
s7_s_section (int ignore)
{
obj_elf_section (ignore);
- if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
record_alignment (now_seg, 2);
}
{
case 'r':
seg = subseg_new (s7_RDATA_SECTION_NAME, (subsegT) get_absolute_expression ());
- bfd_set_section_flags (stdoutput, seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA));
+ bfd_set_section_flags (seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_RELOC | SEC_DATA));
if (strcmp (TARGET_OS, "elf") != 0)
record_alignment (seg, 4);
demand_empty_rest_of_line ();
break;
case 's':
seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
- bfd_set_section_flags (stdoutput, seg, SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
+ bfd_set_section_flags (seg, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA | SEC_SMALL_DATA));
if (strcmp (TARGET_OS, "elf") != 0)
record_alignment (seg, 4);
demand_empty_rest_of_line ();
char *name;
symbolS *p;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
p = (symbolS *) symbol_find_or_make (name);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
return p;
}
if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
s7_get_number ();
-#ifdef BFD_ASSEMBLER
- if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
- maybe_text = 1;
- else
- maybe_text = 0;
-#else
- if (now_seg != data_section && now_seg != bss_section)
+ if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
maybe_text = 1;
else
maybe_text = 0;
-#endif
if (!maybe_text)
as_warn (_(".ent or .aent not in text section."));
if (!aent && s7_cur_proc_ptr)
else
p = NULL;
-#ifdef BFD_ASSEMBLER
- if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
- maybe_text = 1;
- else
- maybe_text = 0;
-#else
- if (now_seg != data_section && now_seg != bss_section)
+ if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
maybe_text = 1;
else
maybe_text = 0;
-#endif
if (!maybe_text)
as_warn (_(".end not in text section"));
segT bss_seg = bss_section;
int needs_align = 0;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
p = input_line_pointer;
*p = c;
return;
}
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
/* Accept an optional comma after the name. The comma used to be
required, but Irix 5 cc does not generate it. */
{
/* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
if ((unsigned) temp <= bfd_get_gp_size (stdoutput))
- {
- bss_seg = subseg_new (".sbss", 1);
- seg_info (bss_seg)->bss = 1;
-#ifdef BFD_ASSEMBLER
- if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
- as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
-#endif
- }
+ {
+ bss_seg = subseg_new (".sbss", 1);
+ seg_info (bss_seg)->bss = 1;
+ if (!bfd_set_section_flags (bss_seg, SEC_ALLOC | SEC_SMALL_DATA))
+ as_warn (_("error setting flags for \".sbss\": %s"),
+ bfd_errmsg (bfd_get_error ()));
+ }
}
#endif
*p = c;
if (
-#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
- || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
-#ifdef BFD_ASSEMBLER
+#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
(OUTPUT_FLAVOR != bfd_target_aout_flavour
|| (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&
-#else
- (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&
-#endif
#endif
(S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
{
segT seg;
subsegT subseg;
- if ((s7_score_ops_hsh = hash_new ()) == NULL)
+ if ((s7_score_ops_hsh = str_htab_create ()) == NULL)
as_fatal (_("virtual memory exhausted"));
s7_build_score_ops_hsh ();
- if ((s7_dependency_insn_hsh = hash_new ()) == NULL)
+ if ((s7_dependency_insn_hsh = str_htab_create ()) == NULL)
as_fatal (_("virtual memory exhausted"));
s7_build_dependency_insn_hsh ();
seg = now_seg;
subseg = now_subseg;
s7_pdr_seg = subseg_new (".pdr", (subsegT) 0);
- (void) bfd_set_section_flags (stdoutput, s7_pdr_seg, SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
- (void) bfd_set_section_alignment (stdoutput, s7_pdr_seg, 2);
+ bfd_set_section_flags (s7_pdr_seg, SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
+ bfd_set_section_alignment (s7_pdr_seg, 2);
subseg_set (seg, subseg);
if (s7_USE_GLOBAL_POINTER_OPT)
the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
the byte sequence 99 99 f1 3f 9a 99 99 99. */
-static char *
+static const char *
s7_atof (int type, char *litP, int *sizeP)
{
int prec;
- LITTLENUM_TYPE words[s7_MAX_LITTLENUMS];
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
char *t;
int i;
grows -= 2;
do_relax_p = 1;
}
- /* Make the 32 bit insturction word align. */
+ /* Make the 32 bit instruction word align. */
else
{
fragp->insn_addr += 2;
else
{
/* Here, try best to do relax regardless fragp->fr_next->fr_type. */
- if (word_align_p == FALSE)
+ if (!word_align_p)
{
if (insn_size % 4 == 0)
{
segT sec ATTRIBUTE_UNUSED,
fragS * fragp)
{
- int r_old;
- int r_new;
+ unsigned int r_old;
+ unsigned int r_new;
char backup[20];
fixS *fixp;
static valueT
s7_section_align (segT segment, valueT size)
{
- int align = bfd_get_section_alignment (stdoutput, segment);
+ int align = bfd_section_alignment (segment);
- return ((size + (1 << align) - 1) & (-1 << align));
+ return ((size + (1 << align) - 1) & -(1 << align));
}
static void
}
else
{
- /* In differnt section. */
+ /* In different section. */
if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
(fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
value = fixP->fx_offset;
static arelent *retval[MAX_RELOC_EXPANSION + 1]; /* MAX_RELOC_EXPANSION equals 2. */
arelent *reloc;
bfd_reloc_code_real_type code;
- char *type;
+ const char *type;
- reloc = retval[0] = xmalloc (sizeof (arelent));
+ reloc = retval[0] = XNEW (arelent);
retval[1] = NULL;
- reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ 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;
reloc->addend = fixp->fx_offset;
newval |= (((off >> 14) & 0x3) << 16);
s7_number_to_chars (buf, newval, s7_INSN_SIZE);
- retval[1] = xmalloc (sizeof (arelent));
+ retval[1] = XNEW (arelent);
retval[2] = NULL;
- retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ retval[1]->sym_ptr_ptr = XNEW (asymbol *);
*retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
retval[1]->address = (reloc->address + s7_RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
code = BFD_RELOC_32_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_HI16_S:
case BFD_RELOC_LO16:
case BFD_RELOC_SCORE_JMP: