/* tc-score7.c -- Assembler for Score7
- Copyright (C) 2009-2017 Free Software Foundation, Inc.
+ Copyright (C) 2009-2021 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. */
{"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));
/* 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;
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,
- (void *) new_opcode);
+ str_hash_insert (s7_score_ops_hsh, new_opcode->template_name,
+ new_opcode, 0);
}
}
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,
- (void *) new_i2d);
+ str_hash_insert (s7_dependency_insn_hsh, new_i2d->insn_name, new_i2d, 0);
}
}
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
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 != NULL)
- symbol_address = (addressT) symbol_get_frag (s)->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. */
\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;
}
buf2[i] = '\0';
- hash_insert (htab, buf, (void *) r);
- hash_insert (htab, buf2, (void *) r);
+ str_hash_insert (htab, buf, r, 0);
+ str_hash_insert (htab, buf2, r, 0);
}
static void
{
const struct s7_reg_entry *r;
- if ((map->htab = hash_new ()) == NULL)
- {
- as_fatal (_("virtual memory exhausted"));
- }
+ map->htab = str_htab_create ();
for (r = map->names; r->name != NULL; r++)
- {
- s7_insert_reg (r, map->htab);
- }
+ s7_insert_reg (r, map->htab);
}
\f
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 ();
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)
+ if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
maybe_text = 1;
else
maybe_text = 0;
-#else
- if (now_seg != data_section && now_seg != bss_section)
- 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)
+ if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
maybe_text = 1;
else
maybe_text = 0;
-#else
- if (now_seg != data_section && now_seg != bss_section)
- maybe_text = 1;
- else
- maybe_text = 0;
-#endif
if (!maybe_text)
as_warn (_(".end not in text section"));
{
/* 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)
- as_fatal (_("virtual memory exhausted"));
+ s7_score_ops_hsh = str_htab_create ();
s7_build_score_ops_hsh ();
- if ((s7_dependency_insn_hsh = hash_new ()) == NULL)
- as_fatal (_("virtual memory exhausted"));
+ s7_dependency_insn_hsh = str_htab_create ();
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)
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));
}
static void
s7_apply_fix (fixS *fixP, valueT *valP, segT seg)
{
- offsetT value = *valP;
- offsetT abs_value = 0;
- offsetT newval;
- offsetT content;
- unsigned short HI, LO;
+ valueT value = *valP;
+ valueT abs_value = 0;
+ valueT newval;
+ valueT content;
+ valueT HI, LO;
char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
if (fixP->fx_done)
{ /* For la rd, imm32. */
newval = s7_md_chars_to_number (buf, s7_INSN_SIZE);
- HI = (value) >> 16; /* mul to 2, then take the hi 16 bit. */
+ HI = value >> 16; /* mul to 2, then take the hi 16 bit. */
newval |= (HI & 0x3fff) << 1;
newval |= ((HI >> 14) & 0x3) << 16;
s7_number_to_chars (buf, newval, s7_INSN_SIZE);
if (fixP->fx_done) /* For la rd, imm32. */
{
newval = s7_md_chars_to_number (buf, s7_INSN_SIZE);
- LO = (value) & 0xffff;
+ LO = value & 0xffff;
newval |= (LO & 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
newval |= ((LO >> 14) & 0x3) << 16;
s7_number_to_chars (buf, newval, s7_INSN_SIZE);
{
content = s7_md_chars_to_number (buf, s7_INSN_SIZE);
value = fixP->fx_offset;
- if (!(value >= 0 && value <= 0x1ffffff))
+ if (value > 0x1ffffff)
{
as_bad_where (fixP->fx_file, fixP->fx_line,
_("j or jl truncate (0x%x) [0 ~ 2^25-1]"), (unsigned int) value);
content = s7_md_chars_to_number (buf, s7_INSN16_SIZE);
content &= 0xf001;
value = fixP->fx_offset;
- if (!(value >= 0 && value <= 0xfff))
+ if (value > 0xfff)
{
as_bad_where (fixP->fx_file, fixP->fx_line,
_("j! or jl! truncate (0x%x) [0 ~ 2^12-1]"), (unsigned int) value);