mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 11:00:01 +08:00
* config/tc-sparc.c (last_opcode): New static local.
(md_assemble): Don't issue "FP branch in delay slot" warning if the delay slot has been annulled.
This commit is contained in:
@ -28,6 +28,13 @@
|
|||||||
#include "opcode/sparc.h"
|
#include "opcode/sparc.h"
|
||||||
|
|
||||||
static void sparc_ip PARAMS ((char *, const struct sparc_opcode **));
|
static void sparc_ip PARAMS ((char *, const struct sparc_opcode **));
|
||||||
|
static int in_signed_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
|
||||||
|
static int in_bitfield_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
|
||||||
|
static int sparc_ffs PARAMS ((unsigned int));
|
||||||
|
static bfd_vma BSR PARAMS ((bfd_vma, int));
|
||||||
|
static int cmp_reg_entry PARAMS ((const PTR, const PTR));
|
||||||
|
static int parse_keyword_arg PARAMS ((int (*) (const char *), char **, int *));
|
||||||
|
static int parse_const_expr_arg PARAMS ((char **, int *));
|
||||||
|
|
||||||
/* Current architecture. We don't bump up unless necessary. */
|
/* Current architecture. We don't bump up unless necessary. */
|
||||||
static enum sparc_opcode_arch_val current_architecture = SPARC_OPCODE_ARCH_V6;
|
static enum sparc_opcode_arch_val current_architecture = SPARC_OPCODE_ARCH_V6;
|
||||||
@ -153,6 +160,9 @@ struct sparc_it
|
|||||||
|
|
||||||
struct sparc_it the_insn, set_insn;
|
struct sparc_it the_insn, set_insn;
|
||||||
|
|
||||||
|
static void output_insn
|
||||||
|
PARAMS ((const struct sparc_opcode *, struct sparc_it *));
|
||||||
|
|
||||||
/* Return non-zero if VAL is in the range -(MAX+1) to MAX. */
|
/* Return non-zero if VAL is in the range -(MAX+1) to MAX. */
|
||||||
|
|
||||||
static INLINE int
|
static INLINE int
|
||||||
@ -237,6 +247,8 @@ static int special_case;
|
|||||||
|
|
||||||
/* The last instruction to be assembled. */
|
/* The last instruction to be assembled. */
|
||||||
static const struct sparc_opcode *last_insn;
|
static const struct sparc_opcode *last_insn;
|
||||||
|
/* The assembled opcode of `last_insn'. */
|
||||||
|
static unsigned long last_opcode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sort of like s_lcomm
|
* sort of like s_lcomm
|
||||||
@ -363,7 +375,7 @@ s_reserve (ignore)
|
|||||||
|
|
||||||
symbolP->sy_frag = frag_now;
|
symbolP->sy_frag = frag_now;
|
||||||
pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
|
pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
|
||||||
size, (char *)0);
|
(offsetT) size, (char *)0);
|
||||||
*pfrag = 0;
|
*pfrag = 0;
|
||||||
|
|
||||||
S_SET_SEGMENT (symbolP, bss_section);
|
S_SET_SEGMENT (symbolP, bss_section);
|
||||||
@ -413,7 +425,7 @@ s_common (ignore)
|
|||||||
*p = 0;
|
*p = 0;
|
||||||
symbolP = symbol_find_or_make (name);
|
symbolP = symbol_find_or_make (name);
|
||||||
*p = c;
|
*p = c;
|
||||||
if (S_IS_DEFINED (symbolP))
|
if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
|
||||||
{
|
{
|
||||||
as_bad ("Ignoring attempt to re-define symbol");
|
as_bad ("Ignoring attempt to re-define symbol");
|
||||||
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
||||||
@ -476,8 +488,8 @@ s_common (ignore)
|
|||||||
if (S_GET_SEGMENT (symbolP) == bss_section)
|
if (S_GET_SEGMENT (symbolP) == bss_section)
|
||||||
symbolP->sy_frag->fr_symbol = 0;
|
symbolP->sy_frag->fr_symbol = 0;
|
||||||
symbolP->sy_frag = frag_now;
|
symbolP->sy_frag = frag_now;
|
||||||
p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
|
p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
|
||||||
(char *) 0);
|
(offsetT) size, (char *) 0);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
S_SET_SEGMENT (symbolP, bss_section);
|
S_SET_SEGMENT (symbolP, bss_section);
|
||||||
S_CLEAR_EXTERNAL (symbolP);
|
S_CLEAR_EXTERNAL (symbolP);
|
||||||
@ -492,8 +504,7 @@ s_common (ignore)
|
|||||||
S_SET_ALIGN (symbolP, temp);
|
S_SET_ALIGN (symbolP, temp);
|
||||||
#endif
|
#endif
|
||||||
S_SET_EXTERNAL (symbolP);
|
S_SET_EXTERNAL (symbolP);
|
||||||
/* should be common, but this is how gas does it for now */
|
S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
|
||||||
S_SET_SEGMENT (symbolP, bfd_und_section_ptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -669,7 +680,7 @@ sparc_cons_align (nbytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
p = frag_var (rs_align_code, 1, 1, (relax_substateT) 0,
|
p = frag_var (rs_align_code, 1, 1, (relax_substateT) 0,
|
||||||
(symbolS *) NULL, (long) nalign, (char *) NULL);
|
(symbolS *) NULL, (offsetT) nalign, (char *) NULL);
|
||||||
|
|
||||||
record_alignment (now_seg, nalign);
|
record_alignment (now_seg, nalign);
|
||||||
}
|
}
|
||||||
@ -716,9 +727,13 @@ struct priv_reg_entry priv_reg_table[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmp_reg_entry (p, q)
|
cmp_reg_entry (parg, qarg)
|
||||||
struct priv_reg_entry *p, *q;
|
const PTR parg;
|
||||||
|
const PTR qarg;
|
||||||
{
|
{
|
||||||
|
const struct priv_reg_entry *p = (const struct priv_reg_entry *) parg;
|
||||||
|
const struct priv_reg_entry *q = (const struct priv_reg_entry *) qarg;
|
||||||
|
|
||||||
return strcmp (q->name, p->name);
|
return strcmp (q->name, p->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,6 +867,7 @@ output_insn (insn, the_insn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
last_insn = insn;
|
last_insn = insn;
|
||||||
|
last_opcode = the_insn->opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -864,11 +880,16 @@ md_assemble (str)
|
|||||||
special_case = 0;
|
special_case = 0;
|
||||||
sparc_ip (str, &insn);
|
sparc_ip (str, &insn);
|
||||||
|
|
||||||
/* We warn about attempts to put a floating point branch in a delay slot. */
|
/* We warn about attempts to put a floating point branch in a delay slot,
|
||||||
|
unless the delay slot has been annulled. */
|
||||||
if (insn != NULL
|
if (insn != NULL
|
||||||
&& last_insn != NULL
|
&& last_insn != NULL
|
||||||
&& (insn->flags & F_FBR) != 0
|
&& (insn->flags & F_FBR) != 0
|
||||||
&& (last_insn->flags & F_DELAYED) != 0)
|
&& (last_insn->flags & F_DELAYED) != 0
|
||||||
|
/* ??? This test isn't completely accurate. We assume anything with
|
||||||
|
F_{UNBR,CONDBR,FBR} set is annullable. */
|
||||||
|
&& ((last_insn->flags & (F_UNBR | F_CONDBR | F_FBR)) == 0
|
||||||
|
|| (last_opcode & ANNUL) == 0))
|
||||||
as_warn ("FP branch in delay slot");
|
as_warn ("FP branch in delay slot");
|
||||||
|
|
||||||
/* SPARC before v9 requires a nop instruction between a floating
|
/* SPARC before v9 requires a nop instruction between a floating
|
||||||
@ -1114,7 +1135,7 @@ md_assemble (str)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
parse_keyword_arg (lookup_fn, input_pointerP, valueP)
|
parse_keyword_arg (lookup_fn, input_pointerP, valueP)
|
||||||
int (*lookup_fn) ();
|
int (*lookup_fn) PARAMS ((const char *));
|
||||||
char **input_pointerP;
|
char **input_pointerP;
|
||||||
int *valueP;
|
int *valueP;
|
||||||
{
|
{
|
||||||
@ -2308,7 +2329,6 @@ md_atof (type, litP, sizeP)
|
|||||||
int i,prec;
|
int i,prec;
|
||||||
LITTLENUM_TYPE words[MAX_LITTLENUMS];
|
LITTLENUM_TYPE words[MAX_LITTLENUMS];
|
||||||
char *t;
|
char *t;
|
||||||
char *atof_ieee ();
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -2668,6 +2688,7 @@ tc_gen_reloc (section, fixp)
|
|||||||
{
|
{
|
||||||
case BFD_RELOC_32_PCREL_S2:
|
case BFD_RELOC_32_PCREL_S2:
|
||||||
if (! S_IS_DEFINED (fixp->fx_addsy)
|
if (! S_IS_DEFINED (fixp->fx_addsy)
|
||||||
|
|| S_IS_COMMON (fixp->fx_addsy)
|
||||||
|| S_IS_EXTERNAL (fixp->fx_addsy)
|
|| S_IS_EXTERNAL (fixp->fx_addsy)
|
||||||
|| S_IS_WEAK (fixp->fx_addsy))
|
|| S_IS_WEAK (fixp->fx_addsy))
|
||||||
code = BFD_RELOC_SPARC_WPLT30;
|
code = BFD_RELOC_SPARC_WPLT30;
|
||||||
|
Reference in New Issue
Block a user