* 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.
This commit is contained in:
Ian Lance Taylor
1993-08-12 15:52:57 +00:00
parent 8e2184bda0
commit 0aa07269cf
2 changed files with 96 additions and 46 deletions

View File

@ -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) 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 * write.c (merge_data_into_text): Define only if BFD_ASSEMBLER is

View File

@ -102,10 +102,11 @@ static symbolS *insn_label;
/* To output NOP instructions correctly, we need to keep information /* To output NOP instructions correctly, we need to keep information
about the previous two instructions. */ about the previous two instructions. */
/* Whether we are optimizing. We always optimize unless -O0 is given. /* Whether we are optimizing. The default value of 2 means to remove
For the very simple optimizations we do, this is compatible with unneeded NOPs and swap branch instructions when possible. A value
the MIPS assembler. */ of 1 means to not swap branches. A value of 0 means to always
static int mips_optimize = 1; insert NOPs. */
static int mips_optimize = 2;
/* The previous instruction. */ /* The previous instruction. */
static struct mips_cl_insn prev_insn; static struct mips_cl_insn prev_insn;
@ -460,8 +461,10 @@ append_insn (ip, address_expr, reloc_type)
/* A load delay. All load delays delay the use of general /* A load delay. All load delays delay the use of general
register rt for one instruction. */ register rt for one instruction. */
know (prev_insn.insn_mo->pinfo & INSN_WRITE_GPR_T); know (prev_insn.insn_mo->pinfo & INSN_WRITE_GPR_T);
if (insn_uses_reg (ip, if (mips_optimize == 0
(prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT, || insn_uses_reg (ip,
((prev_insn.insn_opcode >> OP_SH_RT)
& OP_MASK_RT),
0)) 0))
++nops; ++nops;
} }
@ -480,7 +483,8 @@ append_insn (ip, address_expr, reloc_type)
all. */ all. */
if (prev_insn.insn_mo->pinfo & INSN_WRITE_FPR_T) if (prev_insn.insn_mo->pinfo & INSN_WRITE_FPR_T)
{ {
if (insn_uses_reg (ip, if (mips_optimize == 0
|| insn_uses_reg (ip,
((prev_insn.insn_opcode >> OP_SH_RT) ((prev_insn.insn_opcode >> OP_SH_RT)
& OP_MASK_RT), & OP_MASK_RT),
1)) 1))
@ -488,7 +492,8 @@ append_insn (ip, address_expr, reloc_type)
} }
else if (prev_insn.insn_mo->pinfo & INSN_WRITE_FPR_D) else if (prev_insn.insn_mo->pinfo & INSN_WRITE_FPR_D)
{ {
if (insn_uses_reg (ip, if (mips_optimize == 0
|| insn_uses_reg (ip,
((prev_insn.insn_opcode >> OP_SH_RD) ((prev_insn.insn_opcode >> OP_SH_RD)
& OP_MASK_RD), & OP_MASK_RD),
1)) 1))
@ -502,8 +507,9 @@ append_insn (ip, address_expr, reloc_type)
instruction may set the condition codes, and the instruction may set the condition codes, and the
current instruction uses them, we must insert two current instruction uses them, we must insert two
NOPS. */ NOPS. */
if ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE) if (mips_optimize == 0
&& (ip->insn_mo->pinfo & INSN_READ_COND_CODE)) || ((prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
&& (ip->insn_mo->pinfo & INSN_READ_COND_CODE)))
nops += 2; nops += 2;
else if (ip->insn_mo->pinfo & INSN_COP) else if (ip->insn_mo->pinfo & INSN_COP)
++nops; ++nops;
@ -516,7 +522,8 @@ append_insn (ip, address_expr, reloc_type)
(this means it is a floating point comparison (this means it is a floating point comparison
instruction). If this instruction uses the condition instruction). If this instruction uses the condition
codes, we need to insert a single NOP. */ 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; ++nops;
} }
else if (prev_insn.insn_mo->pinfo & INSN_READ_LO) 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 /* The previous instruction reads the LO register; if the
current instruction writes to the LO register, we must current instruction writes to the LO register, we must
insert two NOPS. */ insert two NOPS. */
if (ip->insn_mo->pinfo & INSN_WRITE_LO) if (mips_optimize == 0
|| ip->insn_mo->pinfo & INSN_WRITE_LO)
nops += 2; nops += 2;
} }
else if (prev_insn.insn_mo->pinfo & INSN_READ_HI) 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 /* The previous instruction reads the HI register; if the
current instruction writes to the HI register, we must current instruction writes to the HI register, we must
insert a NOP. */ insert a NOP. */
if (ip->insn_mo->pinfo & INSN_WRITE_HI) if (mips_optimize == 0
|| ip->insn_mo->pinfo & INSN_WRITE_HI)
nops += 2; nops += 2;
} }
@ -625,7 +634,7 @@ append_insn (ip, address_expr, reloc_type)
if ((ip->insn_mo->pinfo & INSN_UNCOND_BRANCH_DELAY) if ((ip->insn_mo->pinfo & INSN_UNCOND_BRANCH_DELAY)
|| (ip->insn_mo->pinfo & INSN_COND_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 /* If we had to emit any NOP instructions, then we
already know we can not swap. */ already know we can not swap. */
|| nops != 0 || nops != 0
@ -2469,6 +2478,20 @@ mips_ip (str, ip)
s = expr_end; s = expr_end;
continue; 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 'b': /* base register */
case 'd': /* destination register */ case 'd': /* destination register */
case 's': /* source register */ case 's': /* source register */
@ -2492,8 +2515,12 @@ mips_ip (str, ip)
++s; ++s;
} }
while (isdigit (*s)); while (isdigit (*s));
if (regno > 31)
as_bad ("Invalid register number (%d)", regno);
} }
else if (s[1] == 'f' && s[2] == 'p') else if (*args != 'E' && *args != 'G')
{
if (s[1] == 'f' && s[2] == 'p')
{ {
s += 3; s += 3;
regno = 30; regno = 30;
@ -2515,10 +2542,9 @@ mips_ip (str, ip)
} }
else else
goto notreg; goto notreg;
if (regno > 31)
as_bad ("Invalid register number (%d)", regno);
if (regno == AT && ! mips_noat) if (regno == AT && ! mips_noat)
as_warn ("Used $at without \".set noat\""); as_warn ("Used $at without \".set noat\"");
}
c = *args; c = *args;
if (*s == ' ') if (*s == ' ')
s++; s++;
@ -3001,7 +3027,17 @@ md_parse_option (argP, cntP, vecP)
if (**argP == 'O') 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; return 1;
} }