diff options
author | Catherine Moore <clm@redhat.com> | 2000-02-21 20:00:33 +0000 |
---|---|---|
committer | Catherine Moore <clm@redhat.com> | 2000-02-21 20:00:33 +0000 |
commit | 6b76fefe3bb5636877487e33fd4b6ea14591fec8 (patch) | |
tree | f892ae3c77cd29d2aa529f244d0d3c19c0d281b5 /gas/config/tc-mips.c | |
parent | 750334d7543e810f17faa353e97c1a25217b9053 (diff) | |
download | gdb-6b76fefe3bb5636877487e33fd4b6ea14591fec8.zip gdb-6b76fefe3bb5636877487e33fd4b6ea14591fec8.tar.gz gdb-6b76fefe3bb5636877487e33fd4b6ea14591fec8.tar.bz2 |
* config/tc-mips.c (MF_HILO_INSN): Define.
(mips_7000_hilo_fix): Declare.
(append_insn): Conditionally insert nops after an mfhi/mflo insn.
(md_parse_option): Check for 7000_HILO_FIX options.
(OPTION_M7000_HILO_FIX): Define.
(OPTION_NO_M7000_HILO_FIX): Define.
* doc/c-mips.texi (-mfix7000): Describe.
Diffstat (limited to 'gas/config/tc-mips.c')
-rw-r--r-- | gas/config/tc-mips.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 723357a..f5b4d4e 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -265,6 +265,10 @@ static int mips_32bitmode = 0; #define cop_interlocks (mips_cpu == 4300 \ ) +/* Is this a mfhi or mflo instruction? */ +#define MF_HILO_INSN(PINFO) \ + ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO)) + /* MIPS PIC level. */ enum mips_pic_level @@ -300,6 +304,10 @@ static int mips_trap; static int mips_any_noreorder; +/* Non-zero if nops should be inserted when the register referenced in + an mfhi/mflo instruction is read in the next two instructions. */ +static int mips_7000_hilo_fix; + /* The size of the small data section. */ static int g_switch_value = 8; /* Whether the -G option was used. */ @@ -1551,6 +1559,37 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) || (pinfo & INSN_READ_COND_CODE)) ++nops; } + + /* If we're fixing up mfhi/mflo for the r7000 and the + previous insn was an mfhi/mflo and the current insn + reads the register that the mfhi/mflo wrote to, then + insert two nops. */ + + else if (mips_7000_hilo_fix + && MF_HILO_INSN (prev_pinfo) + && insn_uses_reg (ip, ((prev_insn.insn_opcode >> OP_SH_RD) + & OP_MASK_RD), + MIPS_GR_REG)) + + { + nops += 2; + } + + /* If we're fixing up mfhi/mflo for the r7000 and the + 2nd previous insn was an mfhi/mflo and the current insn + reads the register that the mfhi/mflo wrote to, then + insert one nop. */ + + else if (mips_7000_hilo_fix + && MF_HILO_INSN (prev_prev_insn.insn_opcode) + && insn_uses_reg (ip, ((prev_prev_insn.insn_opcode >> OP_SH_RD) + & OP_MASK_RD), + MIPS_GR_REG)) + + { + nops += 1; + } + else if (prev_pinfo & INSN_READ_LO) { /* The previous instruction reads the LO register; if the @@ -8802,6 +8841,11 @@ struct option md_longopts[] = { #define OPTION_MABI (OPTION_MD_BASE + 38) {"mabi", required_argument, NULL, OPTION_MABI}, +#define OPTION_M7000_HILO_FIX (OPTION_MD_BASE + 39) + {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX}, +#define OPTION_NO_M7000_HILO_FIX (OPTION_MD_BASE + 40) + {"no-fix-7000", no_argument, NULL, OPTION_NO_M7000_HILO_FIX}, + #define OPTION_CALL_SHARED (OPTION_MD_BASE + 7) #define OPTION_NON_SHARED (OPTION_MD_BASE + 8) #define OPTION_XGOT (OPTION_MD_BASE + 19) @@ -9126,6 +9170,14 @@ md_parse_option (c, arg) mips_abi_string = arg; break; + case OPTION_M7000_HILO_FIX: + mips_7000_hilo_fix = true; + break; + + case OPTION_NO_M7000_HILO_FIX: + mips_7000_hilo_fix = false; + break; + default: return 0; } |