From 0aa07269cfb496dd99f9d7d0c8bb052cfdda922d Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 12 Aug 1993 15:52:57 +0000 Subject: [PATCH] * config/tc-mips.c (mips_ip): Suggested by davidj@ICSI.Berkeley.EDU (David Johnson): Don't accept symbolic names for 'E' and 'G' argument types (coprocessor registers) and don't warn if $1 is used on the coprocessor. --- gas/ChangeLog | 14 +++++ gas/config/tc-mips.c | 128 +++++++++++++++++++++++++++---------------- 2 files changed, 96 insertions(+), 46 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 92e10863d04..a33ac42f50a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +Thu Aug 12 11:47:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * config/tc-mips.c (mips_ip): Suggested by + davidj@ICSI.Berkeley.EDU (David Johnson): Don't accept symbolic + names for 'E' and 'G' argument types (coprocessor registers) and + don't warn if $1 is used on the coprocessor. + +Mon Aug 9 12:09:14 1993 Doug Evans (dje@canuck.cygnus.com) + + * read.c (emit_expr): Use BFD_RELOC_16 for 2-byte values. + * config/tc-sparc.c (md_apply_fix, tc_gen_reloc): Handle + BFD_RELOC_16. + * config/tc-sparc.h (WORKING_DOT_WORD): Define. + Mon Aug 9 13:36:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) * write.c (merge_data_into_text): Define only if BFD_ASSEMBLER is diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index bb4c48e7cc4..e0cc5d4fa0e 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -102,10 +102,11 @@ static symbolS *insn_label; /* To output NOP instructions correctly, we need to keep information about the previous two instructions. */ -/* Whether we are optimizing. We always optimize unless -O0 is given. - For the very simple optimizations we do, this is compatible with - the MIPS assembler. */ -static int mips_optimize = 1; +/* Whether we are optimizing. The default value of 2 means to remove + unneeded NOPs and swap branch instructions when possible. A value + of 1 means to not swap branches. A value of 0 means to always + insert NOPs. */ +static int mips_optimize = 2; /* The previous instruction. */ static struct mips_cl_insn prev_insn; @@ -460,9 +461,11 @@ append_insn (ip, address_expr, reloc_type) /* A load delay. All load delays delay the use of general register rt for one instruction. */ know (prev_insn.insn_mo->pinfo & INSN_WRITE_GPR_T); - if (insn_uses_reg (ip, - (prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT, - 0)) + if (mips_optimize == 0 + || insn_uses_reg (ip, + ((prev_insn.insn_opcode >> OP_SH_RT) + & OP_MASK_RT), + 0)) ++nops; } else if (prev_insn.insn_mo->pinfo & INSN_COPROC_DELAY) @@ -480,18 +483,20 @@ append_insn (ip, address_expr, reloc_type) all. */ if (prev_insn.insn_mo->pinfo & INSN_WRITE_FPR_T) { - if (insn_uses_reg (ip, - ((prev_insn.insn_opcode >> OP_SH_RT) - & OP_MASK_RT), - 1)) + if (mips_optimize == 0 + || insn_uses_reg (ip, + ((prev_insn.insn_opcode >> OP_SH_RT) + & OP_MASK_RT), + 1)) ++nops; } else if (prev_insn.insn_mo->pinfo & INSN_WRITE_FPR_D) { - if (insn_uses_reg (ip, - ((prev_insn.insn_opcode >> OP_SH_RD) - & OP_MASK_RD), - 1)) + if (mips_optimize == 0 + || insn_uses_reg (ip, + ((prev_insn.insn_opcode >> OP_SH_RD) + & OP_MASK_RD), + 1)) ++nops; } else @@ -502,8 +507,9 @@ append_insn (ip, address_expr, reloc_type) instruction may set the condition codes, and the current instruction uses them, we must insert two NOPS. */ - if ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE) - && (ip->insn_mo->pinfo & INSN_READ_COND_CODE)) + if (mips_optimize == 0 + || ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE) + && (ip->insn_mo->pinfo & INSN_READ_COND_CODE))) nops += 2; else if (ip->insn_mo->pinfo & INSN_COP) ++nops; @@ -516,7 +522,8 @@ append_insn (ip, address_expr, reloc_type) (this means it is a floating point comparison instruction). If this instruction uses the condition codes, we need to insert a single NOP. */ - if (ip->insn_mo->pinfo & INSN_READ_COND_CODE) + if (mips_optimize == 0 + || ip->insn_mo->pinfo & INSN_READ_COND_CODE) ++nops; } else if (prev_insn.insn_mo->pinfo & INSN_READ_LO) @@ -524,7 +531,8 @@ append_insn (ip, address_expr, reloc_type) /* The previous instruction reads the LO register; if the current instruction writes to the LO register, we must insert two NOPS. */ - if (ip->insn_mo->pinfo & INSN_WRITE_LO) + if (mips_optimize == 0 + || ip->insn_mo->pinfo & INSN_WRITE_LO) nops += 2; } else if (prev_insn.insn_mo->pinfo & INSN_READ_HI) @@ -532,7 +540,8 @@ append_insn (ip, address_expr, reloc_type) /* The previous instruction reads the HI register; if the current instruction writes to the HI register, we must insert a NOP. */ - if (ip->insn_mo->pinfo & INSN_WRITE_HI) + if (mips_optimize == 0 + || ip->insn_mo->pinfo & INSN_WRITE_HI) nops += 2; } @@ -625,7 +634,7 @@ append_insn (ip, address_expr, reloc_type) if ((ip->insn_mo->pinfo & INSN_UNCOND_BRANCH_DELAY) || (ip->insn_mo->pinfo & INSN_COND_BRANCH_DELAY)) { - if (! mips_optimize + if (mips_optimize < 2 /* If we had to emit any NOP instructions, then we already know we can not swap. */ || nops != 0 @@ -2469,6 +2478,20 @@ mips_ip (str, ip) s = expr_end; continue; + case 'C': /* Coprocessor code */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned long) imm_expr.X_add_number >= (1<<25)) + { + as_warn ("Coproccesor code > 25 bits (%d)", + imm_expr.X_add_number); + imm_expr.X_add_number &= ((1<<25) - 1); + } + ip->insn_opcode |= imm_expr.X_add_number; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + case 'b': /* base register */ case 'd': /* destination register */ case 's': /* source register */ @@ -2492,33 +2515,36 @@ mips_ip (str, ip) ++s; } while (isdigit (*s)); + if (regno > 31) + as_bad ("Invalid register number (%d)", regno); } - else if (s[1] == 'f' && s[2] == 'p') - { - s += 3; - regno = 30; - } - else if (s[1] == 's' && s[2] == 'p') - { - s += 3; - regno = 29; - } - else if (s[1] == 'g' && s[2] == 'p') - { - s += 3; - regno = 28; - } - else if (s[1] == 'a' && s[2] == 't') + else if (*args != 'E' && *args != 'G') { - s += 3; - regno = 1; + if (s[1] == 'f' && s[2] == 'p') + { + s += 3; + regno = 30; + } + else if (s[1] == 's' && s[2] == 'p') + { + s += 3; + regno = 29; + } + else if (s[1] == 'g' && s[2] == 'p') + { + s += 3; + regno = 28; + } + else if (s[1] == 'a' && s[2] == 't') + { + s += 3; + regno = 1; + } + else + goto notreg; + if (regno == AT && ! mips_noat) + as_warn ("Used $at without \".set noat\""); } - else - goto notreg; - if (regno > 31) - as_bad ("Invalid register number (%d)", regno); - if (regno == AT && !mips_noat) - as_warn ("Used $at without \".set noat\""); c = *args; if (*s == ' ') s++; @@ -3001,7 +3027,17 @@ md_parse_option (argP, cntP, vecP) if (**argP == 'O') { - mips_optimize = (*argP)[1] != '0'; + if ((*argP)[1] == '0') + mips_optimize = 1; + else + mips_optimize = 2; + return 1; + } + + if (**argP == 'g') + { + if ((*argP)[1] == '\0' || (*argP)[1] == '2') + mips_optimize = 0; return 1; } -- 2.30.2