This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v4] Fixups of Loongson2F


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" "" \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]