* 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.
This commit is contained in:
parent
95631471e2
commit
1048a9ba65
3 changed files with 108 additions and 3 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue