2009-05-26 Catherine Moore <clm@codesourcery.com>

gas/
            * config/tc-mips.c (check_for_24k_errata): Remove.
            (md_mips_end): Remove call to check_for_24k_errata.
            (start_noreorder): Likewise.
            (s_change_sec): Likewise.
            (s_change_section): Likewise.
            (insns_between): Add 24k errata checks.
            (append_insn): Remove declaration and references to nhdx_24k.
            Remove calls to check_for_24k_errata.

            gas/testsuite:
            * eret.s, eret.d eret.l: Remove.
            * eret-1.s, eret-1.d: New.
            * eret-2.s, eret-2.d: New.
            * eret-3.s, eret-3.d: New.
            * mips.exp: Run new tests.  Remove old tests.
This commit is contained in:
Catherine Moore
2009-05-27 14:14:42 +00:00
parent 3614867c42
commit ff2390383b
11 changed files with 106 additions and 110 deletions

View File

@ -1,3 +1,14 @@
2009-05-26 Catherine Moore <clm@codesourcery.com>
* config/tc-mips.c (check_for_24k_errata): Remove.
(md_mips_end): Remove call to check_for_24k_errata.
(start_noreorder): Likewise.
(s_change_sec): Likewise.
(s_change_section): Likewise.
(insns_between): Add 24k errata checks.
(append_insn): Remove declaration and references to nhdx_24k.
Remove calls to check_for_24k_errata.
2009-05-26 Nick Clifton <nickc@redhat.com> 2009-05-26 Nick Clifton <nickc@redhat.com>
* po/id.po: Updated Indonesian translation. * po/id.po: Updated Indonesian translation.

View File

@ -1792,85 +1792,6 @@ reg_lookup (char **s, unsigned int types, unsigned int *regnop)
return reg >= 0; return reg >= 0;
} }
#define INSN_ERET 0x42000018
#define INSN_DERET 0x4200001f
/* Implement the ERET/DERET Errata for MIPS 24k.
If an ERET/DERET is encountered in a noreorder block,
warn if the ERET/DERET is followed by a branch instruction.
Also warn if the ERET/DERET is the last instruction in the
noreorder block.
IF an ERET/DERET is in a reorder block and is followed by a
branch instruction, insert a nop. */
static void
check_for_24k_errata (struct mips_cl_insn *insn, int eret_ndx)
{
bfd_boolean next_insn_is_branch = FALSE;
/* eret_ndx will be -1 for the last instruction in a section
and the ERET/DERET will be in insn, not history. */
if (insn
&& eret_ndx == -1
&& (insn->insn_opcode == INSN_ERET
|| insn->insn_opcode == INSN_DERET)
&& insn->noreorder_p)
{
as_warn (_("ERET and DERET must be followed by a NOP on the 24K."));
return;
}
if (history[eret_ndx].insn_opcode != INSN_ERET
&& history[eret_ndx].insn_opcode != INSN_DERET)
return;
if (!insn)
{
if (history[eret_ndx].noreorder_p)
as_warn (_("ERET and DERET must be followed by a NOP on the 24K."));
return;
}
next_insn_is_branch = ((insn->insn_opcode == INSN_ERET)
|| (insn->insn_opcode == INSN_DERET)
|| (insn->insn_mo->pinfo
& (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
| INSN_COND_BRANCH_LIKELY)));
if (next_insn_is_branch && history[eret_ndx].noreorder_p)
{
as_warn (_("ERET and DERET must be followed by a NOP on the 24K."));
return;
}
/* Emit nop if the next instruction is a branch. */
if (next_insn_is_branch)
{
long nop_where, br_where;
struct frag *nop_frag, *br_frag;
struct mips_cl_insn br_insn, nop_insn;
emit_nop ();
nop_insn = history[eret_ndx - 1];
nop_frag = history[eret_ndx - 1].frag;
nop_where = history[eret_ndx - 1].where;
br_insn = history[eret_ndx];
br_frag = history[eret_ndx].frag;
br_where = history[eret_ndx].where;
move_insn (&nop_insn, br_frag, br_where);
move_insn (&br_insn, nop_frag, nop_where);
history[eret_ndx-1] = br_insn;
history[eret_ndx] = nop_insn;
}
}
/* Return TRUE if opcode MO is valid on the currently selected ISA and /* Return TRUE if opcode MO is valid on the currently selected ISA and
architecture. If EXPANSIONP is TRUE then this check is done while architecture. If EXPANSIONP is TRUE then this check is done while
expanding a macro. Use is_opcode_valid_16 for MIPS16 opcodes. */ expanding a macro. Use is_opcode_valid_16 for MIPS16 opcodes. */
@ -2156,9 +2077,6 @@ md_begin (void)
void void
md_mips_end (void) md_mips_end (void)
{ {
if (mips_fix_24k)
check_for_24k_errata ((struct mips_cl_insn *) &history[0], -1);
if (! ECOFF_DEBUGGING) if (! ECOFF_DEBUGGING)
md_obj_end (); md_obj_end ();
} }
@ -2536,6 +2454,9 @@ classify_vr4120_insn (const char *name)
return NUM_FIX_VR4120_CLASSES; return NUM_FIX_VR4120_CLASSES;
} }
#define INSN_ERET 0x42000018
#define INSN_DERET 0x4200001f
/* Return the number of instructions that must separate INSN1 and INSN2, /* Return the number of instructions that must separate INSN1 and INSN2,
where INSN1 is the earlier instruction. Return the worst-case value where INSN1 is the earlier instruction. Return the worst-case value
for any INSN2 if INSN2 is null. */ for any INSN2 if INSN2 is null. */
@ -2573,6 +2494,24 @@ insns_between (const struct mips_cl_insn *insn1,
&& INSN2_USES_REG (EXTRACT_OPERAND (RD, *insn1), MIPS_GR_REG)) && INSN2_USES_REG (EXTRACT_OPERAND (RD, *insn1), MIPS_GR_REG))
return 2; return 2;
/* If we're working around 24K errata, one instruction is required
if an ERET or DERET is followed by a branch instruction. */
if (mips_fix_24k)
{
if (insn1->insn_opcode == INSN_ERET
|| insn1->insn_opcode == INSN_DERET)
{
if (insn2 == NULL
|| insn2->insn_opcode == INSN_ERET
|| insn2->insn_opcode == INSN_DERET
|| (insn2->insn_mo->pinfo
& (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
| INSN_COND_BRANCH_LIKELY)) != 0)
return 1;
}
}
/* If working around VR4120 errata, check for combinations that need /* If working around VR4120 errata, check for combinations that need
a single intervening instruction. */ a single intervening instruction. */
if (mips_fix_vr4120) if (mips_fix_vr4120)
@ -2789,7 +2728,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
bfd_reloc_code_real_type *reloc_type) bfd_reloc_code_real_type *reloc_type)
{ {
unsigned long prev_pinfo, pinfo; unsigned long prev_pinfo, pinfo;
int hndx_24k = 0;
relax_stateT prev_insn_frag_type = 0; relax_stateT prev_insn_frag_type = 0;
bfd_boolean relaxed_branch = FALSE; bfd_boolean relaxed_branch = FALSE;
segment_info_type *si = seg_info (now_seg); segment_info_type *si = seg_info (now_seg);
@ -3347,8 +3285,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
slot, and bump the destination address. */ slot, and bump the destination address. */
insert_into_history (0, 1, ip); insert_into_history (0, 1, ip);
emit_nop (); emit_nop ();
if (mips_fix_24k)
hndx_24k++;
} }
if (mips_relax.sequence) if (mips_relax.sequence)
@ -3389,11 +3325,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
insn information. */ insn information. */
if (pinfo & INSN_UNCOND_BRANCH_DELAY) if (pinfo & INSN_UNCOND_BRANCH_DELAY)
{ {
/* Check for eret/deret before clearing history. */
if (mips_fix_24k)
check_for_24k_errata (
(struct mips_cl_insn *) &history[hndx_24k],
hndx_24k+1);
mips_no_prev_insn (); mips_no_prev_insn ();
} }
} }
@ -3405,8 +3336,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
the next instruction. */ the next instruction. */
insert_into_history (0, 1, ip); insert_into_history (0, 1, ip);
emit_nop (); emit_nop ();
if (mips_fix_24k)
hndx_24k++;
} }
else else
insert_into_history (0, 1, ip); insert_into_history (0, 1, ip);
@ -3414,10 +3343,6 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
else else
insert_into_history (0, 1, ip); insert_into_history (0, 1, ip);
if (mips_fix_24k)
check_for_24k_errata ((struct mips_cl_insn *) &history[hndx_24k],
hndx_24k+1);
/* We just output an insn, so the next one doesn't have a label. */ /* We just output an insn, so the next one doesn't have a label. */
mips_clear_insn_labels (); mips_clear_insn_labels ();
} }
@ -3504,8 +3429,6 @@ start_noreorder (void)
static void static void
end_noreorder (void) end_noreorder (void)
{ {
if (mips_fix_24k)
check_for_24k_errata (NULL, 0);
mips_opts.noreorder--; mips_opts.noreorder--;
if (mips_opts.noreorder == 0 && prev_nop_frag != NULL) if (mips_opts.noreorder == 0 && prev_nop_frag != NULL)
@ -12588,9 +12511,6 @@ s_change_sec (int sec)
mips_emit_delays (); mips_emit_delays ();
if (mips_fix_24k)
check_for_24k_errata ((struct mips_cl_insn *) &history[0], -1);
switch (sec) switch (sec)
{ {
case 't': case 't':
@ -12649,9 +12569,6 @@ s_change_section (int ignore ATTRIBUTE_UNUSED)
if (!IS_ELF) if (!IS_ELF)
return; return;
if (mips_fix_24k)
check_for_24k_errata ((struct mips_cl_insn *) &history[0], -1);
section_name = input_line_pointer; section_name = input_line_pointer;
c = get_symbol_end (); c = get_symbol_end ();
if (c) if (c)

View File

@ -1,3 +1,16 @@
2009-05-26 Catherine Moore <clm@codesourcery.com>
* gas/mips/eret.s: Remove.
* gas/mips/ eret.d: Remove.
* gas/mips/eret.l: Remove.
* gas/mips/eret-1.s: New.
* gas/mips/eret-1.d: New.
* gas/mips/eret-2.s: New.
* gas/mips/eret-2.d: New.
* gas/mips/eret-3.s: New.
* gas/mips/eret-3.d: New.
* gas/mips/mips.exp: Run new tests. Remove old tests.
2009-05-23 Richard Sandiford <rdsandiford@googlemail.com> 2009-05-23 Richard Sandiford <rdsandiford@googlemail.com>
* gas/mips/vr4130.s, gas/mips/vr4130.d: Expect part A to have nops. * gas/mips/vr4130.s, gas/mips/vr4130.d: Expect part A to have nops.

View File

@ -1,5 +1,5 @@
#objdump: -d #objdump: -d
#name: MIPS eret disassembly #name: MIPS eret-1 disassembly
#as: -mfix-24k -march=24kc --no-warn #as: -mfix-24k -march=24kc --no-warn
.*\.o: file format .*mips.* .*\.o: file format .*mips.*

View File

@ -0,0 +1,16 @@
#objdump: -d
#name: MIPS eret-2 disassembly
#as: -mfix-24k -march=24kc --no-warn
.*\.o: file format .*mips.*
Disassembly of section \.text:
00000000 <\.text>:
0: 42000018 eret
4: 00000000 nop
8: 1000fffd b 0x0
c: 00000000 nop
10: 42000018 eret
14: 00000000 nop
18: 1000fffd b 0x10

View File

@ -0,0 +1,9 @@
.set noreorder
1: eret
.set reorder
b 1b
1: eret
.set noreorder
b 1b
.set reorder

View File

@ -0,0 +1,18 @@
#objdump: -d
#name: MIPS eret-3 disassembly
#as: -mfix-24k -march=24kc --no-warn
.*\.o: file format .*mips.*
Disassembly of section \.text:
00000000 <foo>:
0: 42000018 eret
4: 00000000 nop
00000008 <bar>:
8: 10800002 beqz a0,14 <bar\+0xc>
c: 00000000 nop
10: aca40000 sw a0,0\(a1\)
14: 03e00008 jr ra
18: 00000000 nop

View File

@ -0,0 +1,14 @@
.globl foo
.ent foo
foo:
eret
.end foo
.globl bar
.ent bar
bar:
beq $4,$0,1f
sw $4,0($5)
1:
jr $31
.end bar

View File

@ -1,3 +0,0 @@
.*\.s: Assembler messages:
.*\.s:20: Warning: ERET and DERET must be followed by a NOP on the 24K\.
.*\.s:27: Warning: ERET and DERET must be followed by a NOP on the 24K\.

View File

@ -436,8 +436,9 @@ if { [istarget mips*-*-vxworks*] } {
} else { } else {
run_dump_test "jal" run_dump_test "jal"
} }
run_dump_test "eret" run_dump_test "eret-1"
run_list_test "eret" "-mfix-24k -march=24kc" "MIPS eret warnings" run_dump_test "eret-2"
run_dump_test "eret-3"
if $elf { run_dump_test "jal-svr4pic" } if $elf { run_dump_test "jal-svr4pic" }
if $elf { run_dump_test "jal-xgot" } if $elf { run_dump_test "jal-xgot" }