Permalink
Browse files

binutils-2.25: Added -mfix-ls3a-llsc and -mnofix-ls3a-llsc option

    Change md_assemble() to insert sync before "ll" or "lld" instruction.
    These options is used to control whether insert "sync" instruction
    before "ll" or "lld" instrction. By default, we insert "sync" before
    "ll/lld" if we don't use those options.

    Test:
    Command:$ cat Test.s
            ll $t0, 16($sp)
    Command:$ as -mfix-loongson3-llsc Test.s -o a.out
            [Or Command:$ as Test.s -o a.out ]
    Command:$ objdump -d a.out > Test_obj.s
    Command:$ cat Test_obj.s
            00000000 <.text>:
               0:   0000000f        sync
               4:   c3a80010        ll      t0,16(sp)
    This commit same as binutils-2.24-23.fc21.loongson.2.src.rpm
    The patch in src rpm ware patch32.

Change-Id: I6f2701472afb1a6936b8f302887cc78ff01c7791

This contains also modifications from @xen0n:

*   Ported to binutils 2.25;
*   Style cleanups;
*   Avoided re-emitting in case the current `ll/lld` already is preceded
    by a `sync`.

Conflicts:
	gas/config/tc-mips.c
  • Loading branch information...
xuchenghua authored and xen0n committed Oct 20, 2015
1 parent c29838e commit 25f26fc06e904323434981037e93a9df7b131ee2
Showing with 61 additions and 2 deletions.
  1. +61 −2 gas/config/tc-mips.c
View
@@ -937,6 +937,16 @@ static int mips_fix_rm7000;
/* ...likewise -mfix-cn63xxp1 */
static bfd_boolean mips_fix_cn63xxp1;
/* ...likewise -mfix-loongson3-llsc
* Default is add sync before ll/lld
* So make the default value as one.
*/
static bfd_boolean mips_fix_loongson3_llsc = TRUE;
/* NOTE(xen0n): For not re-emitting sync if the current ll/lld already
* has a preceding sync. */
static bfd_boolean mips_loongson3_prev_insn_is_sync = FALSE;
/* We don't relax branches by default, since this causes us to expand
`la .l2 - .l1' if there's a branch between .l1 and .l2, because we
fail to compute the offset before expanding the macro to the most
@@ -1433,6 +1443,8 @@ enum options
OPTION_NO_FIX_24K,
OPTION_FIX_RM7000,
OPTION_NO_FIX_RM7000,
OPTION_FIX_LOONGSON3_LLSC,
OPTION_NO_FIX_LOONGSON3_LLSC,
OPTION_FIX_LOONGSON2F_JUMP,
OPTION_NO_FIX_LOONGSON2F_JUMP,
OPTION_FIX_LOONGSON2F_NOP,
@@ -1561,6 +1573,8 @@ struct option md_longopts[] =
{"mno-fix-24k", no_argument, NULL, OPTION_NO_FIX_24K},
{"mfix-rm7000", no_argument, NULL, OPTION_FIX_RM7000},
{"mno-fix-rm7000", no_argument, NULL, OPTION_NO_FIX_RM7000},
{"mfix-loongson3-llsc", no_argument, NULL, OPTION_FIX_LOONGSON3_LLSC},
{"mno-fix-loongson3-llsc", no_argument, NULL, OPTION_NO_FIX_LOONGSON3_LLSC},
{"mfix-cn63xxp1", no_argument, NULL, OPTION_FIX_CN63XXP1},
{"mno-fix-cn63xxp1", no_argument, NULL, OPTION_NO_FIX_CN63XXP1},
@@ -4009,9 +4023,41 @@ md_assemble (char *str)
str, insn.insn_opcode));
}
if (insn_error.msg)
if (insn_error.msg) {
report_insn_error (str);
else if (insn.insn_mo->pinfo == INSN_MACRO)
goto out;
}
if (mips_fix_loongson3_llsc == TRUE)
{
static expressionS bak_imm_expr;
static expressionS bak_offset_expr;
static bfd_reloc_code_real_type bak_offset_reloc[3] ;
/* NOTE(xen0n): Don't re-emit if already preceded by a sync. */
if ((mips_loongson3_prev_insn_is_sync == FALSE)
&& ((strcmp (insn.insn_mo->name, "ll") == 0)
|| (strcmp (insn.insn_mo->name, "lld") == 0)))
{
bak_imm_expr = imm_expr;
bak_offset_expr = offset_expr;
bak_offset_reloc[0] = offset_reloc[0];
bak_offset_reloc[1] = offset_reloc[1];
bak_offset_reloc[2] = offset_reloc[2];
md_assemble("sync");
imm_expr = bak_imm_expr;
offset_expr = bak_offset_expr;
offset_reloc[0] = bak_offset_reloc[0];
offset_reloc[1] = bak_offset_reloc[1];
offset_reloc[2] = bak_offset_reloc[2];
}
}
if (insn.insn_mo->pinfo == INSN_MACRO)
{
macro_start ();
if (mips_opts.mips16)
@@ -4028,6 +4074,7 @@ md_assemble (char *str)
append_insn (&insn, NULL, unused_reloc, FALSE);
}
out:
mips_assembling_insn = FALSE;
}
@@ -7002,6 +7049,10 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
if (mips_fix_loongson2f && !HAVE_CODE_COMPRESSION)
fix_loongson2f (ip);
/* NOTE(xen0n): Only update flag if the fix is enabled. */
if (mips_fix_loongson3_llsc == TRUE)
mips_loongson3_prev_insn_is_sync = strcmp (ip->insn_mo->name, "sync") == 0;
file_ase_mips16 |= mips_opts.mips16;
file_ase_micromips |= mips_opts.micromips;
@@ -14240,6 +14291,14 @@ md_parse_option (int c, char *arg)
mips_fix_rm7000 = 0;
break;
case OPTION_FIX_LOONGSON3_LLSC:
mips_fix_loongson3_llsc = TRUE;
break;
case OPTION_NO_FIX_LOONGSON3_LLSC:
mips_fix_loongson3_llsc = FALSE;
break;
case OPTION_FIX_LOONGSON2F_JUMP:
mips_fix_loongson2f_jump = TRUE;
break;

0 comments on commit 25f26fc

Please sign in to comment.