This is the mail archive of the binutils@sources.redhat.com 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]

Committed, CRIS: helper functionality to avoid hw multiplication/cache bug


See <URL:http://developer.axis.com/doc/hardware/etrax100lx/des_ref/errata_etrax_100lx.html>
"Multiply operations and cache behavior" and <URL:http://gcc.gnu.org/PR14471>.

Will commit to 2.15 too.

gas/ChangeLog:

	* doc/c-cris.texi (CRIS-Opts): Document --no-mul-bug-abort,
	--mul-bug-abort and the default behavior.
	* config/tc-cris.c (cris_insn_kind): New member CRIS_INSN_MUL.
	(err_for_dangerous_mul_placement): New variable.
	(STATE_MUL, OPTION_MULBUG_ABORT_ON, OPTION_MULBUG_ABORT_OFF): New
	macros.
	(md_cris_relax_table): Have placeholder for STATE_MUL.
	(md_longopts): New options --mul-bug-abort and --no-mul-bug-abort.
	(cris_relax_frag) <case ENCODE_RELAX (STATE_MUL, STATE_BYTE)>: New
	case doing nothing.
	(md_estimate_size_before_relax) <case ENCODE_RELAX (STATE_MUL,
	STATE_BYTE)>: Ditto.
	(md_convert_frag) <ENCODE_RELAX (STATE_MUL, STATE_BYTE)>: Check
	alignment and position of this frag, emit error message if
	suspicious.
	(md_assemble): For a multiply insn and when checking it,
	transform the current frag into a special frag for that purpose.
	(md_parse_option) <case OPTION_MULBUG_ABORT_OFF, case
	OPTION_MULBUG_ABORT_ON>: Handle new options.

gas/testsuite/ChangeLog:

	* gas/cris/regreg.d: Assemble with --no-mul-bug-abort.
	* gas/cris/mulbug-err-1.s, gas/cris/rd-mulbug-1.d: New tests.

gas/testsuite/gas/cris/mulbug-err-1.s::
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ gas/testsuite/gas/cris/mulbug-err-1.s	Thu Feb 26 16:43:37 2004
@@ -0,0 +1,55 @@
+; Test error message for mul insns at locations likely to trig
+; a hardware bug.
+
+;  { dg-do assemble { target cris-*-* } }
+
+ ; First, .text isn't dword-aligned by default.
+ .text
+ muls.w $r1,$r4 ; { dg-error "align" }
+ nop
+ muls.b $r1,$r4 ; { dg-error "align" }
+ mulu.d $r1,$r4 ; { dg-error "align" }
+
+; Neither are other code sections, aligned to word.
+ .section .text.1,"ax",@progbits
+ .p2align 1
+ muls.w $r1,$r4 ; { dg-error "align" }
+ nop
+ mulu.b $r1,$r4 ; { dg-error "align" }
+ muls.d $r1,$r4 ; { dg-error "align" }
+
+; Now, a section aligned to dword.  Errors for certain relative
+; positions only.
+ .section .text.2,"ax",@progbits
+ .p2align 2
+ mulu.w $r1,$r4
+ nop
+ muls.d $r1,$r4
+ mulu.w $r1,$r4 ; { dg-error "align" }
+
+; For good measure, a cache-line-aligned section.
+ .section .text.3,"ax",@progbits
+ .p2align 5
+ muls.w $r1,$r4
+ mulu.d $r4,$r1
+ mulu.b $r1,$r4
+ .rept 12
+ nop
+ .endr
+ mulu.b $r1,$r4 ; { dg-error "align" }
+ mulu.b $r1,$r4
+
+; Last, make sure typical alignment use by a fixed gcc passes.
+ .section .text.4,"ax",@progbits
+ .align 1
+ moveq 0,$r13
+ moveq 1,$r13
+ .p2alignw 5,0x050f,2
+ muls.d $r1,$r4
+ .rept 12
+ moveq 2,$r13
+ .endr
+ .p2alignw 5,0x050f,2
+ muls.w $r1,$r4
+ .p2alignw 5,0x050f,2
+ muls.b $r4,$r1

gas/testsuite/gas/cris/rd-mulbug-1.d::
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ gas/testsuite/gas/cris/rd-mulbug-1.d	Thu Feb 26 16:50:52 2004
@@ -0,0 +1,24 @@
+#objdump: -s
+#source: mulbug-err-1.s
+#as: --em=criself --no-mul-bug-abort
+
+# Check that we don't get any errors or messages with
+# "--no-mul-bug-abort".  No checking for "--mul-bug-abort",
+# though.
+
+.*:     file format .*-cris
+
+Contents of section \.text:
+ 0+ 114d0f05 014d2149                    .*
+Contents of section \.text\.1:
+ 0+ 114d0f05 0149214d                    .*
+Contents of section \.text\.2:
+ 0+ 11490f05 214d1149                    .*
+Contents of section \.text\.3:
+ 0+ 114d2419 01490f05 0f050f05 0f050f05  .*
+ 0+10 0f050f05 0f050f05 0f050f05 0f050149  .*
+ 0+20 0149                                 .*
+Contents of section \.text\.4:
+ 0+ 40d241d2 214d42d2 42d242d2 42d242d2  .*
+ 0+10 42d242d2 42d242d2 42d242d2 42d20f05  .*
+ 0+20 114d041d                             .*

Index: gas/config/tc-cris.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-cris.c,v
retrieving revision 1.28
diff -c -p -r1.28 tc-cris.c
*** gas/config/tc-cris.c	21 Nov 2003 00:24:40 -0000	1.28
--- gas/config/tc-cris.c	21 Mar 2004 22:59:00 -0000
***************
*** 58,64 ****
     Note that some prefix-insns might be assembled as CRIS_INSN_NORMAL.  */
  enum cris_insn_kind
  {
!   CRIS_INSN_NORMAL, CRIS_INSN_NONE, CRIS_INSN_BRANCH
  };
  
  /* An instruction will have one of these prefixes.
--- 58,64 ----
     Note that some prefix-insns might be assembled as CRIS_INSN_NORMAL.  */
  enum cris_insn_kind
  {
!   CRIS_INSN_NORMAL, CRIS_INSN_NONE, CRIS_INSN_BRANCH, CRIS_INSN_MUL
  };
  
  /* An instruction will have one of these prefixes.
*************** const pseudo_typeS md_pseudo_table[] =
*** 187,192 ****
--- 187,196 ----
  
  static int warn_for_branch_expansion = 0;
  
+ /* Whether to emit error when a MULS/MULU could be located last on a
+    cache-line.  */
+ static int err_for_dangerous_mul_placement = 1;
+ 
  const char cris_comment_chars[] = ";";
  
  /* This array holds the chars that only start a comment at the beginning of
*************** const char FLT_CHARS[] = "";
*** 219,228 ****
        length: byte, word, 10-byte expansion
  
     2. BDAP
!       length: byte, word, dword  */
  
  #define STATE_CONDITIONAL_BRANCH    (1)
  #define STATE_BASE_PLUS_DISP_PREFIX (2)
  
  #define STATE_LENGTH_MASK	    (3)
  #define STATE_BYTE		    (0)
--- 223,238 ----
        length: byte, word, 10-byte expansion
  
     2. BDAP
!       length: byte, word, dword
! 
!    3. MULS/MULU
!       Not really a relaxation (no infrastructure to get delay-slots
!       right), just an alignment and placement checker for the v10
!       multiply/cache-bug.  */
  
  #define STATE_CONDITIONAL_BRANCH    (1)
  #define STATE_BASE_PLUS_DISP_PREFIX (2)
+ #define STATE_MUL		    (3)
  
  #define STATE_LENGTH_MASK	    (3)
  #define STATE_BYTE		    (0)
*************** const relax_typeS md_cris_relax_table[] 
*** 282,288 ****
    {BDAP_WF,   BDAP_WB,	 2,  ENCODE_RELAX (2, 2)},
  
    /* BDAP.d [PC+] (2, 2).  */
!   {0,	      0,	 4,  0}
  };
  
  #undef BRANCH_BF
--- 292,304 ----
    {BDAP_WF,   BDAP_WB,	 2,  ENCODE_RELAX (2, 2)},
  
    /* BDAP.d [PC+] (2, 2).  */
!   {0,	      0,	 4,  0},
! 
!   /* Unused (2, 3).  */
!   {0,	      0,	 0,  0},
! 
!   /* MULS/MULU (3, 0).  Positions (3, 1..3) are unused.  */
!   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}
  };
  
  #undef BRANCH_BF
*************** struct option md_longopts[] =
*** 304,309 ****
--- 320,329 ----
    {"underscore", no_argument, NULL, OPTION_US},
  #define OPTION_PIC (OPTION_MD_BASE + 2)
    {"pic", no_argument, NULL, OPTION_PIC},
+ #define OPTION_MULBUG_ABORT_ON (OPTION_MD_BASE + 3)
+   {"mul-bug-abort", no_argument, NULL, OPTION_MULBUG_ABORT_ON},
+ #define OPTION_MULBUG_ABORT_OFF (OPTION_MD_BASE + 4)
+   {"no-mul-bug-abort", no_argument, NULL, OPTION_MULBUG_ABORT_OFF},
    {NULL, no_argument, NULL, 0}
  };
  
*************** cris_relax_frag (seg, fragP, stretch)
*** 392,397 ****
--- 412,421 ----
        aim = S_GET_VALUE (symbolP);
        break;
  
+     case ENCODE_RELAX (STATE_MUL, STATE_BYTE):
+       /* Nothing to do here.  */
+       return 0;
+ 
      default:
        as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
  		  __FUNCTION__, fragP->fr_subtype);
*************** md_estimate_size_before_relax (fragP, se
*** 558,563 ****
--- 582,591 ----
        fragP->fr_var = md_cris_relax_table[fragP->fr_subtype].rlx_length;
        break;
  
+     case ENCODE_RELAX (STATE_MUL, STATE_BYTE):
+       /* Nothing to do here.  */
+       break;
+ 
      default:
        BAD_CASE (fragP->fr_subtype);
      }
*************** md_convert_frag (abfd, sec, fragP)
*** 679,684 ****
--- 707,730 ----
        var_part_size = 4;
        break;
  
+     case ENCODE_RELAX (STATE_MUL, STATE_BYTE):
+       /* This is the only time we check position and aligmnent of the
+ 	 placement-tracking frag.  */
+       if (sec->alignment_power < 2)
+ 	as_bad_where (fragP->fr_file, fragP->fr_line,
+ 		      _("section alignment must be >= 4 bytes to check MULS/MULU safeness"));
+       else
+ 	{
+ 	  /* If the address after the MULS/MULU has alignment which is
+ 	     that of the section and may be that of a cache-size of the
+ 	     buggy versions, then the MULS/MULU can be placed badly.  */
+ 	  if ((address_of_var_part
+ 	       & ((1 << sec->alignment_power) - 1) & 31) == 0)
+ 	    as_bad_where (fragP->fr_file, fragP->fr_line,
+ 			  _("dangerous MULS/MULU location; give it higher alignment"));
+ 	}
+       break;
+ 
      default:
        BAD_CASE (fragP->fr_subtype);
        break;
*************** md_assemble (str)
*** 967,972 ****
--- 1013,1025 ----
  			      output_instruction.expr.X_add_number);
  	}
      }
+   else if (output_instruction.insn_type == CRIS_INSN_MUL
+ 	   && err_for_dangerous_mul_placement)
+     /* Create a frag which which we track the location of the mul insn
+        (in the last two bytes before the mul-frag).  */
+     frag_variant (rs_machine_dependent, 0, 0,
+ 		  ENCODE_RELAX (STATE_MUL, STATE_BYTE),
+ 		  NULL, 0, opcodep);
    else
      {
        if (output_instruction.imm_oprnd_size > 0)
*************** cris_process_instruction (insn_text, out
*** 1572,1577 ****
--- 1625,1633 ----
  		      != (unsigned int) out_insnp->imm_oprnd_size))
  		as_bad (_("PIC relocation size does not match operand size"));
  	    }
+ 	  else if (instruction->op == cris_muls_op
+ 		   || instruction->op == cris_mulu_op)
+ 	    out_insnp->insn_type = CRIS_INSN_MUL;
  	}
        break;
      }
*************** md_parse_option (arg, argp)
*** 2945,2950 ****
--- 3001,3014 ----
  
      case OPTION_PIC:
        pic = TRUE;
+       return 1;
+ 
+     case OPTION_MULBUG_ABORT_OFF:
+       err_for_dangerous_mul_placement = 0;
+       return 1;
+ 
+     case OPTION_MULBUG_ABORT_ON:
+       err_for_dangerous_mul_placement = 1;
        return 1;
  
      default:
Index: gas/doc/c-cris.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-cris.texi,v
retrieving revision 1.1
diff -c -p -r1.1 c-cris.texi
*** gas/doc/c-cris.texi	9 Feb 2002 03:12:24 -0000	1.1
--- gas/doc/c-cris.texi	21 Mar 2004 22:59:00 -0000
*************** When @option{-N} is specified, @code{@va
*** 74,79 ****
--- 74,98 ----
  warning when a 16-bit branch instruction is expanded into a
  32-bit multiple-instruction construct (@pxref{CRIS-Expand}).
  
+ @cindex @option{--no-mul-bug-abort} command line option, CRIS
+ @cindex @option{--mul-bug-abort} command line option, CRIS
+ @cindex CRIS @option{--no-mul-bug-abort} command line option
+ @cindex CRIS @option{--mul-bug-abort} command line option
+ 
+ Some versions of the CRIS v10, for example in the Etrax 100 LX,
+ contain a bug that causes destabilizing memory accesses when a
+ multiply instruction is executed with certain values in the
+ first operand just before a cache-miss.  When the
+ @option{--mul-bug-abort} command line option is active (the
+ default value), @code{@value{AS}} will refuse to assemble a file
+ containing a multiply instruction at a dangerous offset, one
+ that could be the last on a cache-line, or is in a section with
+ insufficient alignment.  This placement checking does not catch
+ any case where the multiply instruction is dangerously placed
+ because it is located in a delay-slot.  The
+ @option{--mul-bug-abort} command line option turns off the
+ checking.
+ 
  @node CRIS-Expand
  @section Instruction expansion
  
Index: gas/testsuite/gas/cris/regreg.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/cris/regreg.d,v
retrieving revision 1.3
diff -c -p -r1.3 regreg.d
*** gas/testsuite/gas/cris/regreg.d	15 Jun 2003 23:46:37 -0000	1.3
--- gas/testsuite/gas/cris/regreg.d	21 Mar 2004 22:59:00 -0000
***************
*** 1,4 ****
--- 1,5 ----
  #objdump: -dr
+ #as: --no-mul-bug-abort
  #name: @OC@
  
  # Test the @OC@ insn.

brgds, H-P


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