This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH v4] Fixups of Loongson2F
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Nick Clifton <nickc at redhat dot com>
- Cc: Wu Zhangjin <wuzhangjin at gmail dot com>, wuzj at lemote dot com, Andreas Barth <aba at not dot so dot argh dot org>, zhangfx at lemote dot com, binutils at sourceware dot org, "Maciej W. Rozycki" <macro at linux-mips dot org>, yanh at lemote dot com, admin at heihaier dot org, = <liushiwei at gmail dot com>, Zhang Le <r0bertz at gentoo dot org>
- Date: Thu, 11 Mar 2010 20:36:02 +0000
- Subject: Re: [PATCH v4] Fixups of Loongson2F
- References: <1258617915-9563-1-git-send-email-wuzhangjin@gmail.com> <20100224000937.GA21981@mails.so.argh.org> <4B865C31.3060501@redhat.com> <877hq1nksl.fsf@firetop.home> <4B87C7B8.6010209@redhat.com> <871vg79fwy.fsf@firetop.home>
Richard Sandiford <rdsandiford@googlemail.com> writes:
> Nick Clifton <nickc@redhat.com> writes:
>> Hi Richard, Hi Wu,
>>> Anyway, the reason I don't think it's ready is that I think the
>>> jump changes should be integrated into the existing macro code,
>>> rather than tacked in at the beginning of append_insn.
>>
>> Ok - is this something that you could do ? I would offer, but MIPS
>> assembler is a black art to me.
>
> Sure, I can give it a go. That's probably the fairest way to approach
> it too, given that it's me who's being difficult here. ;-)
OK, how's this? If it looks OK, could someone give it a spin on
affected Loongson 2F hardware and let me know if it works? I'd
especially like to know if the ".set noat" behaviour I was advocating
breaks current kernel builds. If so, I think the right fix is to let
the workarounds be switched on and off using ".set", just like you can
for many other options:
.set push
.set no-fix-loongson2f
...stuff that's known to be safe...
.set pop
We could then remove the special case for $26 and $27.
I think this is better than making ".set noat" disable the workarounds.
".set noat" is a general feature that can be used by people who don't
know about this errata, so there's no guarantee that their code is safe.
Richard
include/opcode/
* mips.h (M_JALR_1, M_JALR_2, M_JR, M_NOP): New macro enums.
opcodes/
* mips-opc.c (nop, jr, jalr): Treat as macros.
gas/
* doc/c-mips.texi (-mfix-loongson2f-jump): Be more specific.
* config/tc-mips.c (mips_fix_loongson2f): Delete.
(fix_loongson2f_nop, fix_loongson2f_jump, fix_loongson2f): Likewise.
(append_insn): Don't call mips_fix_loongson2f.
(append_simple_insn): New function, extracted from...
(md_assemble): ...here.
(macro_build_nop, modify_jump_target): New functions.
(macro_build_jalr, macro_build_jr): Likewise.
(macro_build_jalr): Rename existing function to...
(macro_build_pic_jalr): ...this. Add a used_at parameter and use
the new macro_build_jalr.
(load_delay_nop): Use macro_build_nop.
(load_address): Likewise.
(macro): Use macro_build_nop, macro_build_jr and macro_build_jalr.
Handle M_NOP, M_JR, M_JALR_1 and M_JALR_2. Update calls to what
is now macro_build_pic_jalr.
(macro2): Likewise.
(md_parse_option): Don't set mips_fix_loongson2f.
gas/testsuite/
* gas/mips/loongson-2f-2.s: Swap the explicit and implicit cases.
Add tests for various macro modes.
* gas/mips/loongson-2f-3.s: Test J, JR, single-operand JA{L,}R and
double-operand JA{L,}R for both the "fix" and "no fix" cases.
* gas/mips/loongson-2f-3.d: Require -mips1 -mabi=32. Update after
above changes.
* gas/mips/loongson-2f-4.s, gas/mips/loongson-2f-4.d,
gas/mips/loongson-2f-4.l, gas/mips/loongson-2f-5.s,
gas/mips/loongson-2f-5.l: New tests.
* gas/mips/mips.exp: Run them.
Index: include/opcode/mips.h
===================================================================
--- include/opcode/mips.h 2010-03-06 15:20:45.000000000 +0000
+++ include/opcode/mips.h 2010-03-06 15:23:12.000000000 +0000
@@ -770,6 +770,9 @@ enum
M_JAL_1,
M_JAL_2,
M_JAL_A,
+ M_JALR_1,
+ M_JALR_2,
+ M_JR,
M_L_DOB,
M_L_DAB,
M_LA_AB,
@@ -825,6 +828,7 @@ enum
M_MULO_I,
M_MULOU,
M_MULOU_I,
+ M_NOP,
M_NOR_I,
M_OR_I,
M_REM_3,
Index: opcodes/mips-opc.c
===================================================================
--- opcodes/mips-opc.c 2010-03-06 15:20:45.000000000 +0000
+++ opcodes/mips-opc.c 2010-03-11 20:18:17.000000000 +0000
@@ -187,6 +187,7 @@ const struct mips_opcode mips_builtin_op
/* name, args, match, mask, pinfo, pinfo2, membership */
{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4_32|G3 },
{"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t|FP_S, 0, I4_33 },
+{"nop", "", 0, (int) M_NOP, INSN_MACRO, 0, I1 },
{"nop", "", 0x00000000, 0xffffffff, 0, INSN2_ALIAS, I1 }, /* sll */
{"ssnop", "", 0x00000040, 0xffffffff, 0, INSN2_ALIAS, I32|N55 }, /* sll */
{"ehb", "", 0x000000c0, 0xffffffff, 0, INSN2_ALIAS, I33 }, /* sll */
@@ -712,11 +713,13 @@ const struct mips_opcode mips_builtin_op
{"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 },
{"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 },
{"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 },
+{"jr", "s", 0, (int) M_JR, INSN_MACRO, 0, I1 },
{"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 },
/* jr.hb is officially MIPS{32,64}R2, but it works on R1 as jr with
the same hazard barrier effect. */
{"jr.hb", "s", 0x00000408, 0xfc1fffff, UBD|RD_s, 0, I32 },
-{"j", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, /* jr */
+/* Equivalent to JR. */
+{"j", "s", 0, (int) M_JR, INSN_MACRO, 0, I1 },
/* SVR4 PIC code requires special handling for j, so it must be a
macro. */
{"j", "a", 0, (int) M_J_A, INSN_MACRO, 0, I1 },
@@ -724,7 +727,9 @@ const struct mips_opcode mips_builtin_op
assembler, but will never match user input (because the line above
will match first). */
{"j", "a", 0x08000000, 0xfc000000, UBD, 0, I1 },
+{"jalr", "s", 0, (int) M_JALR_1, INSN_MACRO, 0, I1 },
{"jalr", "s", 0x0000f809, 0xfc1fffff, UBD|RD_s|WR_d, 0, I1 },
+{"jalr", "d,s", 0, (int) M_JALR_2, INSN_MACRO, 0, I1 },
{"jalr", "d,s", 0x00000009, 0xfc1f07ff, UBD|RD_s|WR_d, 0, I1 },
/* jalr.hb is officially MIPS{32,64}R2, but it works on R1 as jalr
with the same hazard barrier effect. */
Index: gas/doc/c-mips.texi
===================================================================
--- gas/doc/c-mips.texi 2010-03-06 15:36:15.000000000 +0000
+++ gas/doc/c-mips.texi 2010-03-11 20:15:04.000000000 +0000
@@ -174,10 +174,15 @@ of an mfhi or mflo instruction occurs in
@item -mfix-loongson2f-jump
@itemx -mno-fix-loongson2f-jump
-Eliminate instruction fetch from outside 256M region to work around the
-Loongson2F @samp{jump} instructions. Without it, under extreme cases,
-the kernel may crash. The issue has been solved in latest processor
-batches, but this fix has no side effect to them.
+Mask the targets of all indirect jumps with @samp{0xffffffffcfffffff},
+unless the target is a kernel register (@samp{$26} or @samp{$27}).
+
+This option works around a Loongson2F errata in which prefetching
+instructions from certain invalid physical addresses could cause
+peripheral devices to deadlock. The option stops any untaken jump
+from accidentally having a @samp{kseg0}, @samp{kseg1} or @samp{xkphys}
+address in the affected range. It is only needed for kernel code,
+and the errata only affects early processor batches.
@item -mfix-loongson2f-nop
@itemx -mno-fix-loongson2f-nop
Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c 2010-03-06 15:20:45.000000000 +0000
+++ gas/config/tc-mips.c 2010-03-11 20:33:07.000000000 +0000
@@ -769,9 +769,6 @@ enum fix_vr4120_class
/* ...likewise -mfix-loongson2f-nop. */
static bfd_boolean mips_fix_loongson2f_nop;
-/* True if -mfix-loongson2f-nop or -mfix-loongson2f-jump passed. */
-static bfd_boolean mips_fix_loongson2f;
-
/* Given two FIX_VR4120_* values X and Y, bit Y of element X is set if
there must be at least one other instruction between an instruction
of type X and an instruction of type Y. */
@@ -1060,6 +1057,8 @@ enum mips_regclass { MIPS_GR_REG, MIPS_F
static void append_insn
(struct mips_cl_insn *, expressionS *, bfd_reloc_code_real_type *);
+static void append_simple_insn
+ (struct mips_cl_insn *ip);
static void mips_no_prev_insn (void);
static void macro_build (expressionS *, const char *, const char *, ...);
static void mips16_macro_build
@@ -2111,8 +2110,6 @@ md_mips_end (void)
md_assemble (char *str)
{
struct mips_cl_insn insn;
- bfd_reloc_code_real_type unused_reloc[3]
- = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
imm_expr.X_op = O_absent;
imm2_expr.X_op = O_absent;
@@ -2155,7 +2152,7 @@ md_assemble (char *str)
else if (offset_expr.X_op != O_absent)
append_insn (&insn, &offset_expr, offset_reloc);
else
- append_insn (&insn, NULL, unused_reloc);
+ append_simple_insn (&insn);
}
}
@@ -2745,54 +2742,6 @@ nops_for_insn_or_target (const struct mi
return nops;
}
-/* Fix NOP issue: Replace nops by "or at,at,zero". */
-
-static void
-fix_loongson2f_nop (struct mips_cl_insn * ip)
-{
- if (strcmp (ip->insn_mo->name, "nop") == 0)
- ip->insn_opcode = LOONGSON2F_NOP_INSN;
-}
-
-/* Fix Jump Issue: Eliminate instruction fetch from outside 256M region
- jr target pc &= 'hffff_ffff_cfff_ffff. */
-
-static void
-fix_loongson2f_jump (struct mips_cl_insn * ip)
-{
- if (strcmp (ip->insn_mo->name, "j") == 0
- || strcmp (ip->insn_mo->name, "jr") == 0
- || strcmp (ip->insn_mo->name, "jalr") == 0)
- {
- int sreg;
- expressionS ep;
-
- if (! mips_opts.at)
- return;
-
- sreg = EXTRACT_OPERAND (RS, *ip);
- if (sreg == ZERO || sreg == KT0 || sreg == KT1 || sreg == ATREG)
- return;
-
- ep.X_op = O_constant;
- ep.X_add_number = 0xcfff0000;
- macro_build (&ep, "lui", "t,u", ATREG, BFD_RELOC_HI16);
- ep.X_add_number = 0xffff;
- macro_build (&ep, "ori", "t,r,i", ATREG, ATREG, BFD_RELOC_LO16);
- macro_build (NULL, "and", "d,v,t", sreg, sreg, ATREG);
- }
-}
-
-static void
-fix_loongson2f (struct mips_cl_insn * ip)
-{
- if (mips_fix_loongson2f_nop)
- fix_loongson2f_nop (ip);
-
- if (mips_fix_loongson2f_jump)
- fix_loongson2f_jump (ip);
-}
-
/* Output an instruction. IP is the instruction information.
ADDRESS_EXPR is an operand of the instruction to be used with
RELOC_TYPE. */
@@ -2806,9 +2755,6 @@ append_insn (struct mips_cl_insn *ip, ex
bfd_boolean relaxed_branch = FALSE;
segment_info_type *si = seg_info (now_seg);
- if (mips_fix_loongson2f)
- fix_loongson2f (ip);
-
/* Mark instruction labels in mips16 mode. */
mips16_mark_labels ();
@@ -3424,6 +3370,17 @@ append_insn (struct mips_cl_insn *ip, ex
mips_clear_insn_labels ();
}
+/* Like append_insn, but assume that the instruction has no operands. */
+
+static void
+append_simple_insn (struct mips_cl_insn *ip)
+{
+ bfd_reloc_code_real_type unused_reloc[3] = {
+ BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED
+ };
+ append_insn (ip, NULL, unused_reloc);
+}
+
/* Forget that there was any previous instruction or label. */
static void
@@ -3963,6 +3920,58 @@ mips16_macro_build (expressionS *ep, con
append_insn (&insn, ep, r);
}
+/* Add a NOP to the current macro expansion. */
+
+static void
+macro_build_nop (void)
+{
+ append_simple_insn (NOP_INSN);
+}
+
+/* The current macro expansion is about to jump to register TARGET.
+ Apply any necessary workarounds. Set *USED_AT if the workarounds
+ use the AT register. */
+
+static void
+modify_jump_target (unsigned int target, int *used_at)
+{
+ expressionS ep;
+
+ if (mips_fix_loongson2f_jump
+ && target != ZERO
+ && target != KT0
+ && target != KT1)
+ {
+ ep.X_op = O_constant;
+ ep.X_add_number = 0xcfff0000;
+ macro_build (&ep, "lui", "t,u", ATREG, BFD_RELOC_HI16);
+ ep.X_add_number = 0xffff;
+ macro_build (&ep, "ori", "t,r,i", ATREG, ATREG, BFD_RELOC_LO16);
+ macro_build (NULL, "and", "d,v,t", target, target, ATREG);
+ *used_at = 1;
+ }
+}
+
+/* Add the equivalent of "JALR DREG,SREG" to the current macro expansion.
+ Set *USED_AT if the sequence uses $at internally. */
+
+static void
+macro_build_jalr (unsigned int dreg, unsigned int sreg, int *used_at)
+{
+ modify_jump_target (sreg, used_at);
+ macro_build (NULL, "jalr", "d,s", dreg, sreg);
+}
+
+/* Add the equivalent of "JR TARGET" to the current macro expansion.
+ Set *USED_AT if the sequence uses $at internally. */
+
+static void
+macro_build_jr (unsigned int target, int *used_at)
+{
+ modify_jump_target (target, used_at);
+ macro_build (NULL, "jr", "s", target);
+}
+
/*
* Sign-extend 32-bit mode constants that have bit 31 set and all
* higher bits unset.
@@ -3995,7 +4004,7 @@ normalize_address_expr (expressionS *ex)
* function. This occurs in NewABI PIC code.
*/
static void
-macro_build_jalr (expressionS *ep)
+macro_build_pic_jalr (expressionS *ep, int *used_at)
{
char *f = NULL;
@@ -4004,7 +4013,7 @@ macro_build_jalr (expressionS *ep)
frag_grow (8);
f = frag_more (0);
}
- macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
+ macro_build_jalr (RA, PIC_CALL_REG, used_at);
if (MIPS_JALR_HINT_P (ep))
fix_new_exp (frag_now, f - frag_now->fr_literal,
4, ep, FALSE, BFD_RELOC_MIPS_JALR);
@@ -4449,7 +4458,7 @@ load_register (int reg, expressionS *ep,
load_delay_nop (void)
{
if (!gpr_interlocks)
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
}
/* Load an address into a register. */
@@ -4676,7 +4685,7 @@ load_address (int reg, expressionS *ep,
check is required because the lui which starts the main
instruction stream does not refer to $gp, and so will not
insert the nop which may be required. */
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
}
macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
BFD_RELOC_MIPS_GOT16, mips_gp_register);
@@ -4853,7 +4862,7 @@ macro (struct mips_cl_insn *ip)
expr1.X_add_number = 8;
macro_build (&expr1, "bgez", "s,p", sreg);
if (dreg == sreg)
- macro_build (NULL, "nop", "", 0);
+ macro_build_nop ();
else
move_register (dreg, sreg);
macro_build (NULL, dbl ? "dsub" : "sub", "d,v,t", dreg, 0, sreg);
@@ -4931,7 +4940,7 @@ macro (struct mips_cl_insn *ip)
switch (imm_expr.X_add_number)
{
case 0:
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
break;
case 2:
macro_build (NULL, "packrl.ph", "d,s,t", treg, treg, sreg);
@@ -5004,7 +5013,7 @@ macro (struct mips_cl_insn *ip)
do_false:
/* result is always false */
if (! likely)
- macro_build (NULL, "nop", "", 0);
+ macro_build_nop ();
else
macro_build (&offset_expr, "bnel", "s,t,p", 0, 0);
break;
@@ -5422,7 +5431,7 @@ macro (struct mips_cl_insn *ip)
{
expr1.X_add_number = 8;
macro_build (&expr1, "bne", "s,t,p", sreg, AT);
- macro_build (NULL, "nop", "", 0);
+ macro_build_nop ();
/* We want to close the noreorder block as soon as possible, so
that later insns are available for delay slot filling. */
@@ -5989,7 +5998,7 @@ macro (struct mips_cl_insn *ip)
{
/* This is needed because this instruction uses $gp, but
the first instruction on the main stream does not. */
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
}
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
@@ -6180,6 +6189,10 @@ macro (struct mips_cl_insn *ip)
/* AT is not used, just return */
return;
+ case M_JR:
+ macro_build_jr (sreg, &used_at);
+ break;
+
case M_J_A:
/* The j instruction may not be used in PIC code, since it
requires an absolute address. We convert it to a b
@@ -6190,6 +6203,12 @@ macro (struct mips_cl_insn *ip)
macro_build (&offset_expr, "b", "p");
break;
+ case M_JALR_1:
+ dreg = RA;
+ case M_JALR_2:
+ macro_build_jalr (dreg, sreg, &used_at);
+ break;
+
/* The jal instructions must be handled as macros because when
generating PIC code they expand to multi-instruction
sequences. Normally they are simple instructions. */
@@ -6198,13 +6217,13 @@ macro (struct mips_cl_insn *ip)
/* Fall through. */
case M_JAL_2:
if (mips_pic == NO_PIC)
- macro_build (NULL, "jalr", "d,s", dreg, sreg);
+ macro_build_jalr (dreg, sreg, &used_at);
else
{
if (sreg != PIC_CALL_REG)
as_warn (_("MIPS PIC call to register other than $25"));
- macro_build (NULL, "jalr", "d,s", dreg, sreg);
+ macro_build_jalr (dreg, sreg, &used_at);
if (mips_pic == SVR4_PIC && !HAVE_NEWABI)
{
if (mips_cprestore_offset < 0)
@@ -6301,7 +6320,7 @@ macro (struct mips_cl_insn *ip)
relax_end ();
}
- macro_build_jalr (&offset_expr);
+ macro_build_pic_jalr (&offset_expr, &used_at);
}
else
{
@@ -6329,7 +6348,7 @@ macro (struct mips_cl_insn *ip)
load_delay_nop ();
relax_switch ();
if (gpdelay)
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
}
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
PIC_CALL_REG, BFD_RELOC_MIPS_GOT16,
@@ -6338,7 +6357,7 @@ macro (struct mips_cl_insn *ip)
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
PIC_CALL_REG, PIC_CALL_REG, BFD_RELOC_LO16);
relax_end ();
- macro_build_jalr (&offset_expr);
+ macro_build_pic_jalr (&offset_expr, &used_at);
if (mips_cprestore_offset < 0)
as_warn (_("No .cprestore pseudo-op used in PIC code"));
@@ -6357,7 +6376,7 @@ macro (struct mips_cl_insn *ip)
mips_cprestore_valid = 1;
}
if (mips_opts.noreorder)
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
expr1.X_add_number = mips_cprestore_offset;
macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
mips_gp_register,
@@ -6822,7 +6841,7 @@ macro (struct mips_cl_insn *ip)
BFD_RELOC_MIPS_GOT_LO16, tempreg);
relax_switch ();
if (gpdelay)
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
BFD_RELOC_MIPS_GOT16, mips_gp_register);
load_delay_nop ();
@@ -7336,7 +7355,7 @@ macro (struct mips_cl_insn *ip)
relax_switch ();
offset_expr.X_add_number = expr1.X_add_number;
if (gpdelay)
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
BFD_RELOC_MIPS_GOT16, mips_gp_register);
load_delay_nop ();
@@ -7420,6 +7439,10 @@ macro (struct mips_cl_insn *ip)
move_register (dreg, sreg);
break;
+ case M_NOP:
+ macro_build_nop ();
+ break;
+
#ifdef LOSING_COMPILER
default:
/* Try and see if this is a new itbl instruction.
@@ -7523,7 +7546,7 @@ macro2 (struct mips_cl_insn *ip)
{
expr1.X_add_number = 8;
macro_build (&expr1, "beq", "s,t,p", dreg, AT);
- macro_build (NULL, "nop", "", 0);
+ macro_build_nop ();
macro_build (NULL, "break", "c", 6);
}
end_noreorder ();
@@ -7554,7 +7577,7 @@ macro2 (struct mips_cl_insn *ip)
{
expr1.X_add_number = 8;
macro_build (&expr1, "beq", "s,t,p", AT, 0);
- macro_build (NULL, "nop", "", 0);
+ macro_build_nop ();
macro_build (NULL, "break", "c", 6);
}
end_noreorder ();
@@ -8052,17 +8075,17 @@ macro2 (struct mips_cl_insn *ip)
start_noreorder ();
macro_build (NULL, "cfc1", "t,G", treg, RA);
macro_build (NULL, "cfc1", "t,G", treg, RA);
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
expr1.X_add_number = 3;
macro_build (&expr1, "ori", "t,r,i", AT, treg, BFD_RELOC_LO16);
expr1.X_add_number = 2;
macro_build (&expr1, "xori", "t,r,i", AT, AT, BFD_RELOC_LO16);
macro_build (NULL, "ctc1", "t,G", AT, RA);
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
macro_build (NULL, mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S",
dreg, sreg);
macro_build (NULL, "ctc1", "t,G", treg, RA);
- macro_build (NULL, "nop", "");
+ macro_build_nop ();
end_noreorder ();
break;
@@ -11874,8 +11897,6 @@ md_parse_option (int c, char *arg)
return 0;
}
- mips_fix_loongson2f = mips_fix_loongson2f_nop || mips_fix_loongson2f_jump;
-
return 1;
}
Index: gas/testsuite/gas/mips/loongson-2f-2.s
===================================================================
--- gas/testsuite/gas/mips/loongson-2f-2.s 2010-03-06 15:23:32.000000000 +0000
+++ gas/testsuite/gas/mips/loongson-2f-2.s 2010-03-06 15:24:30.000000000 +0000
@@ -2,9 +2,12 @@
.text
.set noreorder
- .align 5 # Test _implicit_ nops
loongson2f_nop_insn:
nop # Test _explicit_ nops
-
-# align section end to 16-byte boundary for easier testing on multiple targets
- .p2align 4
+ .set nomacro # Shouldn't get a diagnostic even in the strictest mode
+ nop
+ .set noat
+ nop
+ .set macro
+ .set at
+ .align 5 # Test _implicit_ nops
Index: gas/testsuite/gas/mips/loongson-2f-3.s
===================================================================
--- gas/testsuite/gas/mips/loongson-2f-3.s 2010-03-06 15:20:45.000000000 +0000
+++ gas/testsuite/gas/mips/loongson-2f-3.s 2010-03-06 15:47:17.000000000 +0000
@@ -2,21 +2,52 @@
.text
.set noreorder
- j $30 # j with register
+ # The following jumps should be masked
+
+ j $30
+ nop
+
+ jr $31
+ nop
+
+ jalr $25
+ nop
+
+ jalr $24,$28
+ nop
+
+ jal $4
+ nop
+
+ jal $5,$6
nop
- jr $31 # jr
+ # The following jumps shouldn't be masked
+
+ j $0
+ nop
+
+ jr $26
nop
- jalr $30 # jalr
+ jalr $27
nop
- .set noat
- jr $1 # jr with at register and .set annotation
- nop
- .set at
+ jalr $24,$26
+ nop
+
+ jal $26
+ nop
+
+ jal $0,$27
+ nop
+
+ # Check that other jumps aren't affected
+
+ j external_label
+ nop
- j external_label # j with label
+ jal external_label
nop
# align section end to 16-byte boundary for easier testing on multiple targets
Index: gas/testsuite/gas/mips/loongson-2f-3.d
===================================================================
--- gas/testsuite/gas/mips/loongson-2f-3.d 2010-03-06 15:20:45.000000000 +0000
+++ gas/testsuite/gas/mips/loongson-2f-3.d 2010-03-06 15:48:22.000000000 +0000
@@ -1,35 +1,59 @@
-#as: -mfix-loongson2f-jump
+#as: -mfix-loongson2f-jump -mabi=32 -mips1
#objdump: -M reg-names=numeric -dr
#name: ST Microelectronics Loongson-2F workarounds of Jump Instruction issue
.*: file format .*
-Disassembly of section .text:
+Disassembly of section \.text:
-00000000 <.text>:
+00000000 <\.text>:
0: 3c01cfff lui \$1,0xcfff
4: 3421ffff ori \$1,\$1,0xffff
8: 03c1f024 and \$30,\$30,\$1
c: 03c00008 jr \$30
10: 00000000 nop
-
14: 3c01cfff lui \$1,0xcfff
18: 3421ffff ori \$1,\$1,0xffff
1c: 03e1f824 and \$31,\$31,\$1
20: 03e00008 jr \$31
24: 00000000 nop
-
28: 3c01cfff lui \$1,0xcfff
2c: 3421ffff ori \$1,\$1,0xffff
- 30: 03c1f024 and \$30,\$30,\$1
- 34: 03c0f809 jalr \$30
+ 30: 0321c824 and \$25,\$25,\$1
+ 34: 0320f809 jalr \$25
38: 00000000 nop
-
- 3c: 00200008 jr \$1
- 40: 00000000 nop
-
- 44: 08000000 j 0x0
- 44: R_MIPS_26 external_label
- 48: 00000000 nop
+ 3c: 3c01cfff lui \$1,0xcfff
+ 40: 3421ffff ori \$1,\$1,0xffff
+ 44: 0381e024 and \$28,\$28,\$1
+ 48: 0380c009 jalr \$24,\$28
4c: 00000000 nop
+ 50: 3c01cfff lui \$1,0xcfff
+ 54: 3421ffff ori \$1,\$1,0xffff
+ 58: 00812024 and \$4,\$4,\$1
+ 5c: 0080f809 jalr \$4
+ 60: 00000000 nop
+ 64: 3c01cfff lui \$1,0xcfff
+ 68: 3421ffff ori \$1,\$1,0xffff
+ 6c: 00c13024 and \$6,\$6,\$1
+ 70: 00c02809 jalr \$5,\$6
+ 74: 00000000 nop
+ 78: 00000008 jr \$0
+ 7c: 00000000 nop
+ 80: 03400008 jr \$26
+ 84: 00000000 nop
+ 88: 0360f809 jalr \$27
+ 8c: 00000000 nop
+ 90: 0340c009 jalr \$24,\$26
+ 94: 00000000 nop
+ 98: 0340f809 jalr \$26
+ 9c: 00000000 nop
+ a0: 03600009 jalr \$0,\$27
+ a4: 00000000 nop
+ a8: 08000000 j 0x0
+ a8: R_MIPS_26 external_label
+ ac: 00000000 nop
+ b0: 0c000000 jal 0x0
+ b0: R_MIPS_26 external_label
+ b4: 00000000 nop
+ \.\.\.
Index: gas/testsuite/gas/mips/loongson-2f-4.s
===================================================================
--- /dev/null 2010-03-11 17:23:26.051174505 +0000
+++ gas/testsuite/gas/mips/loongson-2f-4.s 2010-03-06 15:49:31.000000000 +0000
@@ -0,0 +1,59 @@
+# Test the work around of the Jump instruction Issue of Loongson2F,
+# with nomacro/noreorder
+ .text
+ .set noreorder
+ .set nomacro
+
+ # The following jumps should be masked
+
+ j $30
+ nop
+
+ jr $31
+ nop
+
+ jalr $25
+ nop
+
+ jalr $24,$28
+ nop
+
+ jal $4
+ nop
+
+ jal $5,$6
+ nop
+
+ # The following jumps shouldn't be masked
+
+ j $0
+ nop
+
+ jr $26
+ nop
+
+ jalr $27
+ nop
+
+ jalr $24,$26
+ nop
+
+ jal $26
+ nop
+
+ jal $0,$27
+ nop
+
+ # Check that other jumps aren't affected
+
+ j external_label
+ nop
+
+ jal external_label
+ nop
+
+ .set macro
+ .set reorder
+
+# align section end to 16-byte boundary for easier testing on multiple targets
+ .p2align 4
Index: gas/testsuite/gas/mips/loongson-2f-4.d
===================================================================
--- /dev/null 2010-03-11 17:23:26.051174505 +0000
+++ gas/testsuite/gas/mips/loongson-2f-4.d 2010-03-06 15:48:45.000000000 +0000
@@ -0,0 +1,60 @@
+#as: -mfix-loongson2f-jump -mabi=32 -mips1
+#objdump: -M reg-names=numeric -dr
+#name: ST Microelectronics Loongson-2F workarounds of Jump Instruction issue (with nomacro)
+#stderr: loongson-2f-4.l
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+00000000 <\.text>:
+ 0: 3c01cfff lui \$1,0xcfff
+ 4: 3421ffff ori \$1,\$1,0xffff
+ 8: 03c1f024 and \$30,\$30,\$1
+ c: 03c00008 jr \$30
+ 10: 00000000 nop
+ 14: 3c01cfff lui \$1,0xcfff
+ 18: 3421ffff ori \$1,\$1,0xffff
+ 1c: 03e1f824 and \$31,\$31,\$1
+ 20: 03e00008 jr \$31
+ 24: 00000000 nop
+ 28: 3c01cfff lui \$1,0xcfff
+ 2c: 3421ffff ori \$1,\$1,0xffff
+ 30: 0321c824 and \$25,\$25,\$1
+ 34: 0320f809 jalr \$25
+ 38: 00000000 nop
+ 3c: 3c01cfff lui \$1,0xcfff
+ 40: 3421ffff ori \$1,\$1,0xffff
+ 44: 0381e024 and \$28,\$28,\$1
+ 48: 0380c009 jalr \$24,\$28
+ 4c: 00000000 nop
+ 50: 3c01cfff lui \$1,0xcfff
+ 54: 3421ffff ori \$1,\$1,0xffff
+ 58: 00812024 and \$4,\$4,\$1
+ 5c: 0080f809 jalr \$4
+ 60: 00000000 nop
+ 64: 3c01cfff lui \$1,0xcfff
+ 68: 3421ffff ori \$1,\$1,0xffff
+ 6c: 00c13024 and \$6,\$6,\$1
+ 70: 00c02809 jalr \$5,\$6
+ 74: 00000000 nop
+ 78: 00000008 jr \$0
+ 7c: 00000000 nop
+ 80: 03400008 jr \$26
+ 84: 00000000 nop
+ 88: 0360f809 jalr \$27
+ 8c: 00000000 nop
+ 90: 0340c009 jalr \$24,\$26
+ 94: 00000000 nop
+ 98: 0340f809 jalr \$26
+ 9c: 00000000 nop
+ a0: 03600009 jalr \$0,\$27
+ a4: 00000000 nop
+ a8: 08000000 j 0x0
+ a8: R_MIPS_26 external_label
+ ac: 00000000 nop
+ b0: 0c000000 jal 0x0
+ b0: R_MIPS_26 external_label
+ b4: 00000000 nop
+ \.\.\.
Index: gas/testsuite/gas/mips/loongson-2f-4.l
===================================================================
--- /dev/null 2010-03-11 17:23:26.051174505 +0000
+++ gas/testsuite/gas/mips/loongson-2f-4.l 2010-03-06 15:49:43.000000000 +0000
@@ -0,0 +1,7 @@
+.*: Assembler messages:
+.*:9: Warning: Macro instruction expanded into multiple instructions
+.*:12: Warning: Macro instruction expanded into multiple instructions
+.*:15: Warning: Macro instruction expanded into multiple instructions
+.*:18: Warning: Macro instruction expanded into multiple instructions
+.*:21: Warning: Macro instruction expanded into multiple instructions
+.*:24: Warning: Macro instruction expanded into multiple instructions
Index: gas/testsuite/gas/mips/loongson-2f-5.s
===================================================================
--- /dev/null 2010-03-11 17:23:26.051174505 +0000
+++ gas/testsuite/gas/mips/loongson-2f-5.s 2010-03-06 15:34:54.000000000 +0000
@@ -0,0 +1,4 @@
+ .set noat
+ jr $1
+ .set at
+ jr $1
Index: gas/testsuite/gas/mips/loongson-2f-5.l
===================================================================
--- /dev/null 2010-03-11 17:23:26.051174505 +0000
+++ gas/testsuite/gas/mips/loongson-2f-5.l 2010-03-06 15:55:40.000000000 +0000
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:2: Error: Macro used \$at after ".set noat"
+.*:4: Warning: used \$at without ".set noat"
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
--- gas/testsuite/gas/mips/mips.exp 2010-03-06 15:29:01.000000000 +0000
+++ gas/testsuite/gas/mips/mips.exp 2010-03-06 15:54:03.000000000 +0000
@@ -791,6 +791,8 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test "loongson-2f"
run_dump_test "loongson-2f-2"
run_dump_test "loongson-2f-3"
+ run_dump_test "loongson-2f-4"
+ run_list_test "loongson-2f-5" "-mabi=32 -mips1 -mfix-loongson2f-jump"
run_dump_test_arches "octeon" [mips_arch_list_matching octeon]
run_list_test_arches "octeon-ill" "" \