* doc/c-cris.texi (CRIS-Opts): Document --no-mul-bug-abort,
authorHans-Peter Nilsson <hp@axis.com>
Sun, 21 Mar 2004 23:50:38 +0000 (23:50 +0000)
committerHans-Peter Nilsson <hp@axis.com>
Sun, 21 Mar 2004 23:50:38 +0000 (23:50 +0000)
--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/ChangeLog
gas/config/tc-cris.c
gas/doc/c-cris.texi

index 6350be1..a4c7b14 100644 (file)
@@ -1,3 +1,25 @@
+2004-03-22  Hans-Peter Nilsson  <hp@axis.com>
+
+       * 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.
+
 2004-03-19  Bob Wilson  <bob.wilson@acm.org>
 
        * config/tc-xtensa.c (mark_literal_frags): New function.
index 736261c..e725b88 100644 (file)
@@ -58,7 +58,7 @@
    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_NORMAL, CRIS_INSN_NONE, CRIS_INSN_BRANCH, CRIS_INSN_MUL
 };
 
 /* An instruction will have one of these prefixes.
@@ -187,6 +187,10 @@ const pseudo_typeS md_pseudo_table[] =
 
 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
@@ -219,10 +223,16 @@ const char FLT_CHARS[] = "";
       length: byte, word, 10-byte expansion
 
    2. BDAP
-      length: byte, word, dword  */
+      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)
@@ -282,7 +292,13 @@ const relax_typeS md_cris_relax_table[] =
   {BDAP_WF,   BDAP_WB,  2,  ENCODE_RELAX (2, 2)},
 
   /* BDAP.d [PC+] (2, 2).  */
-  {0,        0,         4,  0}
+  {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
@@ -304,6 +320,10 @@ struct option md_longopts[] =
   {"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}
 };
 
@@ -392,6 +412,10 @@ cris_relax_frag (seg, fragP, stretch)
       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);
@@ -558,6 +582,10 @@ md_estimate_size_before_relax (fragP, segment_type)
       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);
     }
@@ -679,6 +707,24 @@ md_convert_frag (abfd, sec, fragP)
       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;
@@ -967,6 +1013,13 @@ md_assemble (str)
                              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)
@@ -1572,6 +1625,9 @@ cris_process_instruction (insn_text, out_insnp, prefixp)
                      != (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;
     }
@@ -2947,6 +3003,14 @@ md_parse_option (arg, argp)
       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:
       return 0;
     }
index 2551b18..e814767 100644 (file)
@@ -74,6 +74,25 @@ When @option{-N} is specified, @code{@value{AS}} will emit a
 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