[patch] mips 7000 fixup
Catherine Moore
clm@cygnus.com
Fri Feb 18 14:16:00 GMT 2000
Sorry about that last email. I hit send prematurely.
I would like to submit the following patch for gas. It is meant
to address an issue that was discovered with a mips 7000 board.
Apparently, the destination register of an mfhi/mflo is not available
for two instructions. This patch will cause the necessary nops to be
inserted if the -mfix700 option is passed to gas. I am also submitting
a patch to gcc which will recognize and pass the option to gas.
Okay to commit?
Catherine
2000-02-18 Catherine Moore <clm@cygnus.com>
* 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.
Index: doc/c-mips.texi
===================================================================
RCS file: /cvs/cvsfiles/devo/gas/doc/c-mips.texi,v
retrieving revision 1.10.50.1
diff -p -r1.10.50.1 c-mips.texi
*** c-mips.texi 1999/11/03 03:51:38 1.10.50.1
--- c-mips.texi 2000/02/18 21:50:32
*************** Generate code for the MIPS 16 processor.
*** 73,78 ****
--- 73,83 ----
@samp{.set mips16} at the start of the assembly file. @samp{-no-mips16}
turns off this option.
+ @item -mfix7000
+ @itemx -no-mfix7000
+ Cause nops to be inserted if the read of the destination register
+ of an mfhi or mflo instruction occurs in the following two instructions.
+
@item -m4010
@itemx -no-m4010
Generate code for the LSI @sc{r4010} chip. This tells the assembler to
Index: config/tc-mips.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gas/config/tc-mips.c,v
retrieving revision 1.366.10.1
diff -p -r1.366.10.1 tc-mips.c
*** tc-mips.c 1999/11/03 03:51:28 1.366.10.1
--- tc-mips.c 2000/02/18 21:51:30
*************** static int mips_32bitmode = 0;
*** 267,272 ****
--- 267,277 ----
|| mips_cpu == 5400 \
)
+ /* Is this a mfhi or mflo instruction? */
+ #define MF_HILO_INSN(PINFO) \
+ ((PINFO & INSN_WRITE_GPR_D) \
+ && (PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
+
/* MIPS PIC level. */
enum mips_pic_level
*************** static int mips_trap;
*** 302,307 ****
--- 307,316 ----
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. */
*************** append_insn (place, ip, address_expr, re
*** 1557,1562 ****
--- 1566,1604 ----
|| (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)
+ && (pinfo & INSN_READ_GPR_S || pinfo & INSN_READ_GPR_T)
+ && 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)
+ && (pinfo & INSN_READ_GPR_S || pinfo & INSN_READ_GPR_T)
+ && 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
*************** struct option md_longopts[] = {
*** 8897,8902 ****
--- 8939,8949 ----
#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)
*************** md_parse_option (c, arg)
*** 9229,9234 ****
--- 9276,9289 ----
|| strcmp (arg,"o64") == 0
|| strcmp (arg,"eabi") == 0)
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:
More information about the Binutils
mailing list