* config/tc-mips.c (insn_label): Remove.
(struct insn_label_list): Define. (insn_labels, free_insn_labels): New static variables. (mips_clear_insn_labels): New static function. (append_insn): Mark all mips16 text labels, and make them odd. Handle all labels after emitting a nop, not just one. Call mips_clear_insn_labels rather than just clearing insn_label. (mips_emit_delays): Add insns parameter, and use it to decide whether to mark mips16 labels. Handle all labels, not just one. Force mips16 labels to be odd. Change all callers. (mips16_immed): Don't check for an odd branch target. (md_apply_fix): Don't check mips16 mode for a branch reloc. (mips16_extended_frag): Ignore the low bit in a branch target. (md_convert_frag): Likewise. (mips_no_prev_insn): Call mips_clear_insn_labels rather than just clearing insn_label. (mips_align, mips_flush_pending_output, s_cons): Likewise. (s_float_cons, s_gpword): Likewise. (s_align): Use insn_labels rather than insn_label. (s_cons, s_float_cons, s_gpword): Likewise. (mips_frob_file_after_relocs): New function. (mips_define_label): Rewrite to add to insn_labels list. * config/tc-mips.h (tc_frob_file_after_relocs): Define. * ecoff.c (ecoff_build_symbols): If the size of a function comes out odd, increment it.
This commit is contained in:
parent
e682debfa3
commit
fbcfacb75d
@ -1,5 +1,34 @@
|
||||
Tue Dec 17 10:59:32 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* config/tc-mips.c (insn_label): Remove.
|
||||
(struct insn_label_list): Define.
|
||||
(insn_labels, free_insn_labels): New static variables.
|
||||
(mips_clear_insn_labels): New static function.
|
||||
(append_insn): Mark all mips16 text labels, and make them odd.
|
||||
Handle all labels after emitting a nop, not just one. Call
|
||||
mips_clear_insn_labels rather than just clearing insn_label.
|
||||
(mips_emit_delays): Add insns parameter, and use it to decide
|
||||
whether to mark mips16 labels. Handle all labels, not just one.
|
||||
Force mips16 labels to be odd. Change all callers.
|
||||
(mips16_immed): Don't check for an odd branch target.
|
||||
(md_apply_fix): Don't check mips16 mode for a branch reloc.
|
||||
(mips16_extended_frag): Ignore the low bit in a branch target.
|
||||
(md_convert_frag): Likewise.
|
||||
(mips_no_prev_insn): Call mips_clear_insn_labels rather than just
|
||||
clearing insn_label.
|
||||
(mips_align, mips_flush_pending_output, s_cons): Likewise.
|
||||
(s_float_cons, s_gpword): Likewise.
|
||||
(s_align): Use insn_labels rather than insn_label.
|
||||
(s_cons, s_float_cons, s_gpword): Likewise.
|
||||
(mips_frob_file_after_relocs): New function.
|
||||
(mips_define_label): Rewrite to add to insn_labels list.
|
||||
* config/tc-mips.h (tc_frob_file_after_relocs): Define.
|
||||
* ecoff.c (ecoff_build_symbols): If the size of a function comes
|
||||
out odd, increment it.
|
||||
|
||||
* config/tc-mips.c (append_insn): Only update prev_insn when not
|
||||
reordering if place is NULL.
|
||||
|
||||
* config/tc-mips.c (mips16_ip): Check for a missing expression
|
||||
when using the register indirect addressing mode.
|
||||
|
||||
|
@ -259,9 +259,6 @@ static int byte_order;
|
||||
|
||||
static int auto_align = 1;
|
||||
|
||||
/* Symbol labelling the current insn. */
|
||||
static symbolS *insn_label;
|
||||
|
||||
/* When outputting SVR4 PIC code, the assembler needs to know the
|
||||
offset in the stack frame from which to restore the $gp register.
|
||||
This is set by the .cprestore pseudo-op, and saved in this
|
||||
@ -504,7 +501,7 @@ static void append_insn PARAMS ((char *place,
|
||||
bfd_reloc_code_real_type r,
|
||||
boolean));
|
||||
static void mips_no_prev_insn PARAMS ((void));
|
||||
static void mips_emit_delays PARAMS ((void));
|
||||
static void mips_emit_delays PARAMS ((boolean));
|
||||
#ifdef USE_STDARG
|
||||
static void macro_build PARAMS ((char *place, int *counter, expressionS * ep,
|
||||
const char *name, const char *fmt,
|
||||
@ -644,6 +641,30 @@ mips_pop_insert ()
|
||||
pop_insert (mips_nonecoff_pseudo_table);
|
||||
}
|
||||
|
||||
/* Symbols labelling the current insn. */
|
||||
|
||||
struct insn_label_list
|
||||
{
|
||||
struct insn_label_list *next;
|
||||
symbolS *label;
|
||||
};
|
||||
|
||||
static struct insn_label_list *insn_labels;
|
||||
static struct insn_label_list *free_insn_labels;
|
||||
|
||||
static void mips_clear_insn_labels PARAMS ((void));
|
||||
|
||||
static inline void
|
||||
mips_clear_insn_labels ()
|
||||
{
|
||||
register struct insn_label_list **pl;
|
||||
|
||||
for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
|
||||
;
|
||||
*pl = insn_labels;
|
||||
insn_labels = NULL;
|
||||
}
|
||||
|
||||
static char *expr_end;
|
||||
|
||||
/* Expressions which appear in instructions. These are set by
|
||||
@ -1172,6 +1193,27 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
else
|
||||
record_alignment (now_seg, 2);
|
||||
|
||||
/* Mark instruction labels in mips16 mode. This permits the linker
|
||||
to handle them specially, such as generating jalx instructions
|
||||
when needed. We also make them odd for the duration of the
|
||||
assembly, in order to generate the right sort of code. We will
|
||||
make them even in the adjust_symtab routine, while leaving them
|
||||
marked. This is convenient for the debugger and the
|
||||
disassembler. The linker knows to make them odd again. */
|
||||
if (mips16)
|
||||
{
|
||||
struct insn_label_list *l;
|
||||
|
||||
for (l = insn_labels; l != NULL; l = l->next)
|
||||
{
|
||||
#ifdef S_SET_OTHER
|
||||
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||
S_SET_OTHER (l->label, STO_MIPS16);
|
||||
#endif
|
||||
++l->label->sy_value.X_add_number;
|
||||
}
|
||||
}
|
||||
|
||||
prev_pinfo = prev_insn.insn_mo->pinfo;
|
||||
pinfo = ip->insn_mo->pinfo;
|
||||
|
||||
@ -1350,6 +1392,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
fragS *old_frag;
|
||||
unsigned long old_frag_offset;
|
||||
int i;
|
||||
struct insn_label_list *l;
|
||||
|
||||
old_frag = frag_now;
|
||||
old_frag_offset = frag_now_fix ();
|
||||
@ -1371,11 +1414,14 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
frag_grow (40);
|
||||
}
|
||||
|
||||
if (insn_label != NULL)
|
||||
for (l = insn_labels; l != NULL; l = l->next)
|
||||
{
|
||||
assert (S_GET_SEGMENT (insn_label) == now_seg);
|
||||
insn_label->sy_frag = frag_now;
|
||||
S_SET_VALUE (insn_label, (valueT) frag_now_fix ());
|
||||
assert (S_GET_SEGMENT (l->label) == now_seg);
|
||||
l->label->sy_frag = frag_now;
|
||||
S_SET_VALUE (l->label, (valueT) frag_now_fix ());
|
||||
/* mips16 text labels are stored as odd. */
|
||||
if (mips16)
|
||||
++l->label->sy_value.X_add_number;
|
||||
}
|
||||
|
||||
#ifndef NO_ECOFF_DEBUGGING
|
||||
@ -1580,7 +1626,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
whether there is a label on this instruction. If
|
||||
there are any branches to anything other than a
|
||||
label, users must use .set noreorder. */
|
||||
|| insn_label != NULL
|
||||
|| insn_labels != NULL
|
||||
/* If the previous instruction is in a variant frag, we
|
||||
can not do the swap. This does not apply to the
|
||||
mips16, which uses variant frags for different
|
||||
@ -1878,9 +1924,9 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
prev_insn_where = f - frag_now->fr_literal;
|
||||
prev_insn_valid = 1;
|
||||
}
|
||||
else
|
||||
else if (place == NULL)
|
||||
{
|
||||
/* We need to record a bit of uninformation even when we are not
|
||||
/* We need to record a bit of information even when we are not
|
||||
reordering, in order to determine the base address for mips16
|
||||
PC relative relocs. */
|
||||
prev_insn = *ip;
|
||||
@ -1888,7 +1934,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
|
||||
}
|
||||
|
||||
/* We just output an insn, so the next one doesn't have a label. */
|
||||
insn_label = NULL;
|
||||
mips_clear_insn_labels ();
|
||||
}
|
||||
|
||||
/* This function forgets that there was any previous instruction or
|
||||
@ -1905,16 +1951,18 @@ mips_no_prev_insn ()
|
||||
prev_insn_extended = 0;
|
||||
prev_insn_reloc_type = BFD_RELOC_UNUSED;
|
||||
prev_prev_insn_unreordered = 0;
|
||||
insn_label = NULL;
|
||||
mips_clear_insn_labels ();
|
||||
}
|
||||
|
||||
/* This function must be called whenever we turn on noreorder or emit
|
||||
something other than instructions. It inserts any NOPS which might
|
||||
be needed by the previous instruction, and clears the information
|
||||
kept for the previous instructions. */
|
||||
kept for the previous instructions. The INSNS parameter is true if
|
||||
instructions are to follow. */
|
||||
|
||||
static void
|
||||
mips_emit_delays ()
|
||||
mips_emit_delays (insns)
|
||||
boolean insns;
|
||||
{
|
||||
if (! mips_noreorder)
|
||||
{
|
||||
@ -1958,16 +2006,43 @@ mips_emit_delays ()
|
||||
nop = 1;
|
||||
if (nop)
|
||||
{
|
||||
struct insn_label_list *l;
|
||||
|
||||
emit_nop ();
|
||||
if (insn_label != NULL)
|
||||
for (l = insn_labels; l != NULL; l = l->next)
|
||||
{
|
||||
assert (S_GET_SEGMENT (insn_label) == now_seg);
|
||||
insn_label->sy_frag = frag_now;
|
||||
S_SET_VALUE (insn_label, (valueT) frag_now_fix ());
|
||||
assert (S_GET_SEGMENT (l->label) == now_seg);
|
||||
l->label->sy_frag = frag_now;
|
||||
S_SET_VALUE (l->label, (valueT) frag_now_fix ());
|
||||
/* mips16 text labels are stored as odd. */
|
||||
if (mips16)
|
||||
++l->label->sy_value.X_add_number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark instruction labels in mips16 mode. This permits the linker
|
||||
to handle them specially, such as generating jalx instructions
|
||||
when needed. We also make them odd for the duration of the
|
||||
assembly, in order to generate the right sort of code. We will
|
||||
make them even in the adjust_symtab routine, while leaving them
|
||||
marked. This is convenient for the debugger and the
|
||||
disassembler. The linker knows to make them odd again. */
|
||||
if (mips16 && insns)
|
||||
{
|
||||
struct insn_label_list *l;
|
||||
|
||||
for (l = insn_labels; l != NULL; l = l->next)
|
||||
{
|
||||
#ifdef S_SET_OTHER
|
||||
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||
S_SET_OTHER (l->label, STO_MIPS16);
|
||||
#endif
|
||||
if ((l->label->sy_value.X_add_number & 1) == 0)
|
||||
++l->label->sy_value.X_add_number;
|
||||
}
|
||||
}
|
||||
|
||||
mips_no_prev_insn ();
|
||||
}
|
||||
|
||||
@ -2914,7 +2989,7 @@ macro (ip)
|
||||
sub v0,$zero,$a0
|
||||
*/
|
||||
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
|
||||
@ -3372,7 +3447,7 @@ macro (ip)
|
||||
return;
|
||||
}
|
||||
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
macro_build ((char *) NULL, &icnt, NULL,
|
||||
@ -3512,7 +3587,7 @@ macro (ip)
|
||||
s = "ddivu";
|
||||
s2 = "mfhi";
|
||||
do_divu3:
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, treg);
|
||||
@ -5091,7 +5166,7 @@ macro2 (ip)
|
||||
case M_DMULO:
|
||||
dbl = 1;
|
||||
case M_MULO:
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
macro_build ((char *) NULL, &icnt, NULL,
|
||||
@ -5118,7 +5193,7 @@ macro2 (ip)
|
||||
case M_DMULOU:
|
||||
dbl = 1;
|
||||
case M_MULOU:
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
macro_build ((char *) NULL, &icnt, NULL,
|
||||
@ -5464,7 +5539,7 @@ macro2 (ip)
|
||||
* Is the double cfc1 instruction a bug in the mips assembler;
|
||||
* or is there a reason for it?
|
||||
*/
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);
|
||||
@ -5735,7 +5810,7 @@ mips16_macro (ip)
|
||||
case M_REM_3:
|
||||
s = "mfhi";
|
||||
do_div3:
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
macro_build ((char *) NULL, &icnt, NULL,
|
||||
@ -5768,7 +5843,7 @@ mips16_macro (ip)
|
||||
s = "ddivu";
|
||||
s2 = "mfhi";
|
||||
do_divu3:
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
++mips_noreorder;
|
||||
mips_any_noreorder = 1;
|
||||
macro_build ((char *) NULL, &icnt, NULL, s, "0,x,y", xreg, yreg);
|
||||
@ -7257,11 +7332,7 @@ mips16_immed (file, line, type, val, warn, small, ext, insn, use_extend,
|
||||
|
||||
/* Branch offsets have an implicit 0 in the lowest bit. */
|
||||
if (type == 'p' || type == 'q')
|
||||
{
|
||||
if ((val & 1) != 0)
|
||||
as_bad_where (file, line, "branch to odd address");
|
||||
val /= 2;
|
||||
}
|
||||
val /= 2;
|
||||
|
||||
if ((val & ((1 << op->shift) - 1)) != 0
|
||||
|| val < (mintiny << op->shift)
|
||||
@ -8235,8 +8306,7 @@ md_apply_fix (fixP, valueP)
|
||||
* might be deleting the relocation entry (i.e., a branch within
|
||||
* the current segment).
|
||||
*/
|
||||
/* TinyRISC can branch to odd addresses */
|
||||
if ((value & (mips16 ? 0x1 : 0x3)) != 0)
|
||||
if ((value & 0x3) != 0)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line,
|
||||
"Branch to odd address (%lx)", value);
|
||||
value >>= 2;
|
||||
@ -8418,7 +8488,7 @@ mips_align (to, fill, label)
|
||||
int fill;
|
||||
symbolS *label;
|
||||
{
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (false);
|
||||
frag_align (to, fill);
|
||||
record_alignment (now_seg, to);
|
||||
if (label != NULL)
|
||||
@ -8470,7 +8540,8 @@ s_align (x)
|
||||
if (temp)
|
||||
{
|
||||
auto_align = 1;
|
||||
mips_align (temp, (int) temp_fill, insn_label);
|
||||
mips_align (temp, (int) temp_fill,
|
||||
insn_labels != NULL ? insn_labels->label : NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8483,8 +8554,8 @@ s_align (x)
|
||||
void
|
||||
mips_flush_pending_output ()
|
||||
{
|
||||
mips_emit_delays ();
|
||||
insn_label = NULL;
|
||||
mips_emit_delays (false);
|
||||
mips_clear_insn_labels ();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -8500,7 +8571,7 @@ s_change_sec (sec)
|
||||
&& (sec == 'd' || sec == 'r'))
|
||||
sec = 's';
|
||||
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (false);
|
||||
switch (sec)
|
||||
{
|
||||
case 't':
|
||||
@ -8578,11 +8649,11 @@ s_cons (log_size)
|
||||
{
|
||||
symbolS *label;
|
||||
|
||||
label = insn_label;
|
||||
mips_emit_delays ();
|
||||
label = insn_labels != NULL ? insn_labels->label : NULL;
|
||||
mips_emit_delays (false);
|
||||
if (log_size > 0 && auto_align)
|
||||
mips_align (log_size, 0, label);
|
||||
insn_label = NULL;
|
||||
mips_clear_insn_labels ();
|
||||
cons (1 << log_size);
|
||||
}
|
||||
|
||||
@ -8592,9 +8663,9 @@ s_float_cons (type)
|
||||
{
|
||||
symbolS *label;
|
||||
|
||||
label = insn_label;
|
||||
label = insn_labels != NULL ? insn_labels->label : NULL;
|
||||
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (false);
|
||||
|
||||
if (auto_align)
|
||||
if (type == 'd')
|
||||
@ -8602,7 +8673,7 @@ s_float_cons (type)
|
||||
else
|
||||
mips_align (2, 0, label);
|
||||
|
||||
insn_label = NULL;
|
||||
mips_clear_insn_labels ();
|
||||
|
||||
float_cons (type);
|
||||
}
|
||||
@ -8717,7 +8788,7 @@ s_mipsset (x)
|
||||
}
|
||||
else if (strcmp (name, "noreorder") == 0)
|
||||
{
|
||||
mips_emit_delays ();
|
||||
mips_emit_delays (true);
|
||||
mips_noreorder = 1;
|
||||
mips_any_noreorder = 1;
|
||||
}
|
||||
@ -8901,11 +8972,11 @@ s_gpword (ignore)
|
||||
return;
|
||||
}
|
||||
|
||||
label = insn_label;
|
||||
mips_emit_delays ();
|
||||
label = insn_labels != NULL ? insn_labels->label : NULL;
|
||||
mips_emit_delays (true);
|
||||
if (auto_align)
|
||||
mips_align (2, 0, label);
|
||||
insn_label = NULL;
|
||||
mips_clear_insn_labels ();
|
||||
|
||||
expression (&ex);
|
||||
|
||||
@ -9213,7 +9284,13 @@ mips16_extended_frag (fragp, sec, stretch)
|
||||
case it can not be extended) use the address of the
|
||||
instruction whose delay slot it is in. */
|
||||
if (type == 'p' || type == 'q')
|
||||
addr += 2;
|
||||
{
|
||||
addr += 2;
|
||||
/* Ignore the low bit in the target, since it will be set
|
||||
for a text label. */
|
||||
if ((val & 1) != 0)
|
||||
--val;
|
||||
}
|
||||
else if (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype))
|
||||
addr -= 4;
|
||||
else if (RELAX_MIPS16_DSLOT (fragp->fr_subtype))
|
||||
@ -9617,7 +9694,13 @@ md_convert_frag (abfd, asec, fragp)
|
||||
/* The rules for the base address of a PC relative reloc are
|
||||
complicated; see mips16_extended_frag. */
|
||||
if (type == 'p' || type == 'q')
|
||||
addr += 2;
|
||||
{
|
||||
addr += 2;
|
||||
/* Ignore the low bit in the target, since it will be
|
||||
set for a text label. */
|
||||
if ((val & 1) != 0)
|
||||
--val;
|
||||
}
|
||||
else if (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype))
|
||||
addr -= 4;
|
||||
else if (RELAX_MIPS16_DSLOT (fragp->fr_subtype))
|
||||
@ -9678,6 +9761,39 @@ md_convert_frag (abfd, asec, fragp)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
|
||||
/* This function is called after the relocs have been generated.
|
||||
We've been storing mips16 text labels as odd. Here we convert them
|
||||
back to even for the convenience of the debugger. */
|
||||
|
||||
void
|
||||
mips_frob_file_after_relocs ()
|
||||
{
|
||||
asymbol **syms;
|
||||
unsigned int count, i;
|
||||
|
||||
if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
|
||||
return;
|
||||
|
||||
syms = bfd_get_outsymbols (stdoutput);
|
||||
count = bfd_get_symcount (stdoutput);
|
||||
for (i = 0; i < count; i++, syms++)
|
||||
{
|
||||
if (elf_symbol (*syms)->internal_elf_sym.st_other == STO_MIPS16
|
||||
&& ((*syms)->value & 1) != 0)
|
||||
{
|
||||
(*syms)->value &= ~1;
|
||||
/* If the symbol has an odd size, it was probably computed
|
||||
incorrectly, so adjust that as well. */
|
||||
if ((elf_symbol (*syms)->internal_elf_sym.st_size & 1) != 0)
|
||||
++elf_symbol (*syms)->internal_elf_sym.st_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* This function is called whenever a label is defined. It is used
|
||||
when handling branch delays; if a branch has a label, we assume we
|
||||
can not move it. */
|
||||
@ -9686,11 +9802,19 @@ void
|
||||
mips_define_label (sym)
|
||||
symbolS *sym;
|
||||
{
|
||||
insn_label = sym;
|
||||
#ifdef OBJ_ELF
|
||||
if (mips16)
|
||||
S_SET_OTHER (insn_label, STO_MIPS16);
|
||||
#endif
|
||||
struct insn_label_list *l;
|
||||
|
||||
if (free_insn_labels == NULL)
|
||||
l = (struct insn_label_list *) xmalloc (sizeof *l);
|
||||
else
|
||||
{
|
||||
l = free_insn_labels;
|
||||
free_insn_labels = l->next;
|
||||
}
|
||||
|
||||
l->label = sym;
|
||||
l->next = insn_labels;
|
||||
insn_labels = l;
|
||||
}
|
||||
|
||||
/* Decide whether a label is local. This is called by LOCAL_LABEL.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* tc-mips.c -- header file for tc-mips.c.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
/* tc-mips.h -- header file for tc-mips.c.
|
||||
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
Contributed by the OSF and Ralph Campbell.
|
||||
Written by Keith Knowles and Ralph Campbell, working independently.
|
||||
Modified for ECOFF support by Ian Lance Taylor of Cygnus Support.
|
||||
@ -17,8 +17,9 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GAS; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
along with GAS; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#ifndef TC_MIPS
|
||||
|
||||
@ -34,6 +35,11 @@
|
||||
#define MAX_RELOC_EXPANSION 3
|
||||
#define LOCAL_LABELS_FB 1
|
||||
|
||||
/* We don't want to define LOCAL_LABELS_DOLLAR, because $0 is really a
|
||||
reference to a register, not a label. */
|
||||
#undef LOCAL_LABELS_DOLLAR
|
||||
#define LOCAL_LABELS_DOLLAR 0
|
||||
|
||||
/* Maximum symbol offset that can be encoded in a BFD_RELOC_MIPS_GPREL
|
||||
relocation: */
|
||||
#define MAX_GPREL_OFFSET (0x7FF4)
|
||||
@ -41,7 +47,9 @@
|
||||
#define LOCAL_LABEL(name) mips_local_label (name)
|
||||
extern int mips_local_label PARAMS ((const char *));
|
||||
|
||||
#define md_relax_frag(fragp, stretch) (0)
|
||||
#define md_relax_frag(fragp, stretch) mips_relax_frag(fragp, stretch)
|
||||
extern int mips_relax_frag PARAMS ((struct frag *, long));
|
||||
|
||||
#define md_undefined_symbol(name) (0)
|
||||
#define md_operand(x)
|
||||
|
||||
@ -63,9 +71,13 @@ extern int mips_local_label PARAMS ((const char *));
|
||||
#define TARGET_FORMAT mips_target_format()
|
||||
extern const char *mips_target_format ();
|
||||
|
||||
struct mips_cl_insn {
|
||||
unsigned long insn_opcode;
|
||||
const struct mips_opcode *insn_mo;
|
||||
struct mips_cl_insn
|
||||
{
|
||||
unsigned long insn_opcode;
|
||||
const struct mips_opcode *insn_mo;
|
||||
/* The next two fields are used when generating mips16 code. */
|
||||
boolean use_extend;
|
||||
unsigned short extend;
|
||||
};
|
||||
|
||||
extern int tc_get_register PARAMS ((int frame));
|
||||
@ -79,9 +91,18 @@ extern void mips_define_label PARAMS ((struct symbol *));
|
||||
#define tc_frob_file() mips_frob_file ()
|
||||
extern void mips_frob_file PARAMS ((void));
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
#define tc_frob_file_after_relocs mips_frob_file_after_relocs
|
||||
extern void mips_frob_file_after_relocs PARAMS ((void));
|
||||
#endif
|
||||
|
||||
#define TC_CONS_FIX_NEW cons_fix_new_mips
|
||||
extern void cons_fix_new_mips ();
|
||||
|
||||
/* Don't adjust MIPS16 jump relocations to section addresses, so we
|
||||
don't have to worry about the format of the offset in the .o file. */
|
||||
#define tc_fix_adjustable(fixp) ((fixp)->fx_r_type != BFD_RELOC_MIPS16_JMP)
|
||||
|
||||
/* When generating embedded PIC code we must keep PC relative
|
||||
relocations. */
|
||||
#define TC_FORCE_RELOCATION(fixp) mips_force_relocation (fixp)
|
||||
|
Loading…
x
Reference in New Issue
Block a user