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] [MIPS] Implement Errata for 24K and 24KE


Hi Richard,

I've attached a new patch. It adds the testcases that you asked for along with the other cleanups. I had trouble with one section -- this first example:

	.set	noreorder
1:	eret
	.set	reorder
	b	1b

insns_between is called only when the the history insn is not in a noreorder block. For this errata, I think we need to call insns between if we're fixing 24k_errata and 1) the history insn is a noreorder block or 2) the history insn is in a noreorder block and the following instruction is not in a noreorder block. For the above example, insns_between was not called for the eret.

Let me know if this patch looks okay.
Thanks,
Catherine


2009-05-18 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.
        (nops_for_insn): Add check for 24k errata.
        (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.



Richard Sandiford wrote:


One upshot of this is that gas ought to insert nops in the following situations:

	.set	noreorder
1:	eret
	.set	reorder
	b	1b

1:	eret
	.set	noreorder
	b	1b
	.set	reorder


Index: config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.406
diff -p -r1.406 tc-mips.c
*** config/tc-mips.c	22 Apr 2009 11:40:25 -0000	1.406
--- config/tc-mips.c	18 May 2009 21:29:31 -0000
*************** reg_lookup (char **s, unsigned int types
*** 1792,1876 ****
    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
     architecture.  If EXPANSIONP is TRUE then this check is done while
     expanding a macro.  Use is_opcode_valid_16 for MIPS16 opcodes.  */
--- 1792,1797 ----
*************** md_begin (void)
*** 2156,2164 ****
  void
  md_mips_end (void)
  {
-   if (mips_fix_24k)
-     check_for_24k_errata ((struct mips_cl_insn *) &history[0], -1);
- 
    if (! ECOFF_DEBUGGING)
      md_obj_end ();
  }
--- 2077,2082 ----
*************** classify_vr4120_insn (const char *name)
*** 2536,2541 ****
--- 2454,2462 ----
    return NUM_FIX_VR4120_CLASSES;
  }
  
+ #define INSN_ERET  0x42000018
+ #define INSN_DERET 0x4200001f
+ 
  /* Return the number of instructions that must separate INSN1 and INSN2,
     where INSN1 is the earlier instruction.  Return the worst-case value
     for any INSN2 if INSN2 is null.  */
*************** insns_between (const struct mips_cl_insn
*** 2573,2578 ****
--- 2494,2522 ----
        && INSN2_USES_REG (EXTRACT_OPERAND (RD, *insn1), MIPS_GR_REG))
      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 != NULL
+ 	  && (insn1->insn_opcode == INSN_ERET
+              || insn1->insn_opcode == INSN_DERET)
+ 	  && insn2 == NULL)
+ 	return 1;
+ 
+       if ((insn1 != NULL)
+ 	  && (insn2 != NULL)
+ 	  && (insn1->insn_opcode == INSN_ERET
+              || insn1->insn_opcode == INSN_DERET)
+ 	  && ((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)))))
+ 	return 1;
+     }
+ 
    /* If working around VR4120 errata, check for combinations that need
       a single intervening instruction.  */
    if (mips_fix_vr4120)
*************** nops_for_insn (const struct mips_cl_insn
*** 2714,2720 ****
  
    nops = 0;
    for (i = 0; i < MAX_DELAY_NOPS; i++)
!     if (!history[i].noreorder_p)
        {
  	tmp_nops = insns_between (history + i, insn) - i;
  	if (tmp_nops > nops)
--- 2658,2665 ----
  
    nops = 0;
    for (i = 0; i < MAX_DELAY_NOPS; i++)
!     if (!history[i].noreorder_p
! 	|| (mips_fix_24k && insn && !insn->noreorder_p))
        {
  	tmp_nops = insns_between (history + i, insn) - i;
  	if (tmp_nops > nops)
*************** append_insn (struct mips_cl_insn *ip, ex
*** 2790,2796 ****
  	     bfd_reloc_code_real_type *reloc_type)
  {
    unsigned long prev_pinfo, pinfo;
-   int hndx_24k = 0;
    relax_stateT prev_insn_frag_type = 0;
    bfd_boolean relaxed_branch = FALSE;
    segment_info_type *si = seg_info (now_seg);
--- 2735,2740 ----
*************** append_insn (struct mips_cl_insn *ip, ex
*** 3348,3355 ****
  		     slot, and bump the destination address.  */
  		  insert_into_history (0, 1, ip);
  		  emit_nop ();
- 		  if (mips_fix_24k)
- 		    hndx_24k++;
  		}
  		
  	      if (mips_relax.sequence)
--- 3292,3297 ----
*************** append_insn (struct mips_cl_insn *ip, ex
*** 3390,3400 ****
  	     insn information.  */
  	  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 ();
  	    }
  	}
--- 3332,3337 ----
*************** append_insn (struct mips_cl_insn *ip, ex
*** 3406,3413 ****
  	     the next instruction.  */
  	  insert_into_history (0, 1, ip);
  	  emit_nop ();
- 	  if (mips_fix_24k)
- 	    hndx_24k++;
  	}
        else
  	insert_into_history (0, 1, ip);
--- 3343,3348 ----
*************** append_insn (struct mips_cl_insn *ip, ex
*** 3415,3424 ****
    else
      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.  */
    mips_clear_insn_labels ();
  }
--- 3350,3355 ----
*************** start_noreorder (void)
*** 3505,3512 ****
  static void
  end_noreorder (void)
  {
-   if (mips_fix_24k)
-     check_for_24k_errata (NULL, 0);
  
    mips_opts.noreorder--;
    if (mips_opts.noreorder == 0 && prev_nop_frag != NULL)
--- 3436,3441 ----
*************** s_change_sec (int sec)
*** 12589,12597 ****
  
    mips_emit_delays ();
  
-   if (mips_fix_24k)
-     check_for_24k_errata ((struct mips_cl_insn *) &history[0], -1);
- 
    switch (sec)
      {
      case 't':
--- 12518,12523 ----
*************** s_change_section (int ignore ATTRIBUTE_U
*** 12650,12658 ****
    if (!IS_ELF)
      return;
  
-   if (mips_fix_24k)
-     check_for_24k_errata ((struct mips_cl_insn *) &history[0], -1);
- 
    section_name = input_line_pointer;
    c = get_symbol_end ();
    if (c)
--- 12576,12581 ----
Index: testsuite/gas/mips/eret-1.d
===================================================================
RCS file: testsuite/gas/mips/eret-1.d
diff -N testsuite/gas/mips/eret-1.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/eret-1.d	18 May 2009 21:29:31 -0000
***************
*** 0 ****
--- 1,41 ----
+ #objdump: -d
+ #name: MIPS eret-1 disassembly
+ #as: -mfix-24k -march=24kc --no-warn
+ 
+ .*\.o:     file format .*mips.*
+ 
+ Disassembly of section \.text:
+ 
+ 00000000 <\.text>:
+    0:	240c0000 	li	t4,0
+    4:	42000018 	eret
+    8:	00000000 	nop
+    c:	10000003 	b	0x1c
+   10:	00000000 	nop
+   14:	240a0003 	li	t2,3
+   18:	42000018 	eret
+   1c:	24040000 	li	a0,0
+   20:	4200001f 	deret
+   24:	00000000 	nop
+   28:	116afffa 	beq	t3,t2,0x14
+   2c:	00000000 	nop
+   30:	4200001f 	deret
+   34:	00000000 	nop
+   38:	42000018 	eret
+   3c:	00000000 	nop
+   40:	42000018 	eret
+   44:	00000000 	nop
+   48:	1000fff4 	b	0x1c
+   4c:	00000000 	nop
+   50:	240c0004 	li	t4,4
+   54:	4200001f 	deret
+   58:	240c0003 	li	t4,3
+   5c:	42000018 	eret
+   60:	10000005 	b	0x78
+   64:	240c0003 	li	t4,3
+   68:	42000018 	eret
+   6c:	00000000 	nop
+   70:	10000001 	b	0x78
+   74:	240c0003 	li	t4,3
+   78:	240c0003 	li	t4,3
+   7c:	42000018 	eret
Index: testsuite/gas/mips/eret-1.s
===================================================================
RCS file: testsuite/gas/mips/eret-1.s
diff -N testsuite/gas/mips/eret-1.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/eret-1.s	18 May 2009 21:29:31 -0000
***************
*** 0 ****
--- 1,27 ----
+ 	.text
+ 	li $t4, 0
+ 	eret
+ 	b 2f
+ 1:	li $t2, 3
+ 	eret
+ 2:	li $a0, 0
+ 	deret
+ 	beq $t3,$t2,1b
+ 	deret
+ 	eret
+ 	eret
+ 	b 2b
+ 
+ 	.set noreorder
+ 	li $t4, 4
+ 	deret
+ 	li $t4, 3
+ 	eret
+ 	b 1f
+ 	li $t4, 3
+ 	eret
+ 	nop
+ 	b 1f
+ 	li $t4, 3
+ 1:	li $t4, 3
+ 	eret
Index: testsuite/gas/mips/eret-2.d
===================================================================
RCS file: testsuite/gas/mips/eret-2.d
diff -N testsuite/gas/mips/eret-2.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/eret-2.d	18 May 2009 21:29:31 -0000
***************
*** 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
Index: testsuite/gas/mips/eret-2.s
===================================================================
RCS file: testsuite/gas/mips/eret-2.s
diff -N testsuite/gas/mips/eret-2.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/eret-2.s	18 May 2009 21:29:31 -0000
***************
*** 0 ****
--- 1,9 ----
+ 	.set	noreorder
+ 1:	eret
+ 	.set	reorder
+ 	b	1b
+ 
+ 1:	eret
+ 	.set	noreorder
+ 	b	1b
+ 	.set	reorder
Index: testsuite/gas/mips/eret-3.d
===================================================================
RCS file: testsuite/gas/mips/eret-3.d
diff -N testsuite/gas/mips/eret-3.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/eret-3.d	18 May 2009 21:29:31 -0000
***************
*** 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
Index: testsuite/gas/mips/eret-3.s
===================================================================
RCS file: testsuite/gas/mips/eret-3.s
diff -N testsuite/gas/mips/eret-3.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/eret-3.s	18 May 2009 21:29:31 -0000
***************
*** 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
Index: testsuite/gas/mips/eret.d
===================================================================
RCS file: testsuite/gas/mips/eret.d
diff -N testsuite/gas/mips/eret.d
*** testsuite/gas/mips/eret.d	9 Apr 2009 15:55:59 -0000	1.1
--- /dev/null	1 Jan 1970 00:00:00 -0000
***************
*** 1,41 ****
- #objdump: -d
- #name: MIPS eret disassembly
- #as: -mfix-24k -march=24kc --no-warn
- 
- .*\.o:     file format .*mips.*
- 
- Disassembly of section \.text:
- 
- 00000000 <\.text>:
-    0:	240c0000 	li	t4,0
-    4:	42000018 	eret
-    8:	00000000 	nop
-    c:	10000003 	b	0x1c
-   10:	00000000 	nop
-   14:	240a0003 	li	t2,3
-   18:	42000018 	eret
-   1c:	24040000 	li	a0,0
-   20:	4200001f 	deret
-   24:	00000000 	nop
-   28:	116afffa 	beq	t3,t2,0x14
-   2c:	00000000 	nop
-   30:	4200001f 	deret
-   34:	00000000 	nop
-   38:	42000018 	eret
-   3c:	00000000 	nop
-   40:	42000018 	eret
-   44:	00000000 	nop
-   48:	1000fff4 	b	0x1c
-   4c:	00000000 	nop
-   50:	240c0004 	li	t4,4
-   54:	4200001f 	deret
-   58:	240c0003 	li	t4,3
-   5c:	42000018 	eret
-   60:	10000005 	b	0x78
-   64:	240c0003 	li	t4,3
-   68:	42000018 	eret
-   6c:	00000000 	nop
-   70:	10000001 	b	0x78
-   74:	240c0003 	li	t4,3
-   78:	240c0003 	li	t4,3
-   7c:	42000018 	eret
--- 0 ----
Index: testsuite/gas/mips/eret.l
===================================================================
RCS file: testsuite/gas/mips/eret.l
diff -N testsuite/gas/mips/eret.l
*** testsuite/gas/mips/eret.l	9 Apr 2009 15:55:59 -0000	1.1
--- /dev/null	1 Jan 1970 00:00:00 -0000
***************
*** 1,3 ****
- .*\.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\.
--- 0 ----
Index: testsuite/gas/mips/eret.s
===================================================================
RCS file: testsuite/gas/mips/eret.s
diff -N testsuite/gas/mips/eret.s
*** testsuite/gas/mips/eret.s	9 Apr 2009 15:55:59 -0000	1.1
--- /dev/null	1 Jan 1970 00:00:00 -0000
***************
*** 1,27 ****
- 	.text
- 	li $t4, 0
- 	eret
- 	b 2f
- 1:	li $t2, 3
- 	eret
- 2:	li $a0, 0
- 	deret
- 	beq $t3,$t2,1b
- 	deret
- 	eret
- 	eret
- 	b 2b
- 
- 	.set noreorder
- 	li $t4, 4
- 	deret
- 	li $t4, 3
- 	eret
- 	b 1f
- 	li $t4, 3
- 	eret
- 	nop
- 	b 1f
- 	li $t4, 3
- 1:	li $t4, 3
- 	eret
--- 0 ----
Index: testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.150
diff -p -r1.150 mips.exp
*** testsuite/gas/mips/mips.exp	9 Apr 2009 15:55:59 -0000	1.150
--- testsuite/gas/mips/mips.exp	18 May 2009 21:29:31 -0000
*************** if { [istarget mips*-*-vxworks*] } {
*** 436,443 ****
      } else {
  	run_dump_test "jal"
      }
!     run_dump_test "eret"
!     run_list_test "eret" "-mfix-24k -march=24kc" "MIPS eret warnings"
  
      if $elf { run_dump_test "jal-svr4pic" }
      if $elf { run_dump_test "jal-xgot" }
--- 436,444 ----
      } else {
  	run_dump_test "jal"
      }
!     run_dump_test "eret-1"
!     run_dump_test "eret-2"
!     run_dump_test "eret-3"
  
      if $elf { run_dump_test "jal-svr4pic" }
      if $elf { run_dump_test "jal-xgot" }

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