diff options
author | Ian Lance Taylor <ian@airs.com> | 1993-07-27 15:55:35 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1993-07-27 15:55:35 +0000 |
commit | 4e95866e2c5d769e6b7db09ca3247d497af941c9 (patch) | |
tree | ebce151a843520c0b515ce0f5ff85bab88e86dd3 /gas/config | |
parent | 4fe45d22549373aba3a8b72242b5eb10c0dfba2c (diff) | |
download | gdb-4e95866e2c5d769e6b7db09ca3247d497af941c9.zip gdb-4e95866e2c5d769e6b7db09ca3247d497af941c9.tar.gz gdb-4e95866e2c5d769e6b7db09ca3247d497af941c9.tar.bz2 |
* config/tc-mips.c (mips_optimize): New static variable.
(append_insn): If ! mips_optimize, don't swap branches.
(md_parse_option): If -Ox, set mips_optimize accordingly.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-mips.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index db0671e..bb4c48e 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -102,6 +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; + /* The previous instruction. */ static struct mips_cl_insn prev_insn; @@ -126,6 +131,13 @@ static fixS *prev_insn_fixp; /* Non-zero if the previous instruction was in a delay slot. */ static int prev_insn_is_delay_slot; + +/* Non-zero if the previous instruction was in a .set noreorder. */ +static int prev_insn_unreordered; + +/* Non-zero if the previous previous instruction was in a .set + noreorder. */ +static int prev_prev_insn_unreordered; /* Prototypes for static functions. */ @@ -613,15 +625,33 @@ 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 we had to emit any NOP instructions, then we already - know we can not swap. */ - if (nops != 0 + if (! mips_optimize + /* If we had to emit any NOP instructions, then we + already know we can not swap. */ + || nops != 0 /* If we don't even know the previous insn, we can not swap. */ || ! prev_insn_valid /* If the previous insn is already in a branch delay slot, then we can not swap. */ || prev_insn_is_delay_slot + /* If the previous previous insn was in a .set + noreorder, we can't swap. Actually, the MIPS + assembler will swap in this situation. However, gcc + configured -with-gnu-as will generate code like + .set noreorder + lw $4,XXX + .set reorder + INSN + bne $4,$0,foo + in which we can not swap the bne and INSN. If gcc is + not configured -with-gnu-as, it does not output the + .set pseudo-ops. We don't have to check + prev_insn_unreordered, because prev_insn_valid will + be 0 in that case. We don't want to use + prev_prev_insn_valid, because we do want to be able + to swap at the start of a function. */ + || prev_prev_insn_unreordered /* If the branch is itself the target of a branch, we can not swap. We cheat on this; all we check for is whether there is a label on this instruction. If @@ -738,6 +768,8 @@ append_insn (ip, address_expr, reloc_type) prev_insn_is_delay_slot = 0; } + prev_prev_insn_unreordered = prev_insn_unreordered; + prev_insn_unreordered = 0; prev_insn_frag = frag_now; prev_insn_where = f - frag_now->fr_literal; prev_insn_fixp = fixp; @@ -758,6 +790,8 @@ mips_no_prev_insn () prev_prev_insn.insn_mo = &dummy_opcode; prev_insn_valid = 0; prev_insn_is_delay_slot = 0; + prev_insn_unreordered = 0; + prev_prev_insn_unreordered = 0; insn_label = NULL; } @@ -2965,6 +2999,12 @@ md_parse_option (argP, cntP, vecP) return 1; } + if (**argP == 'O') + { + mips_optimize = (*argP)[1] != '0'; + return 1; + } + #ifdef OBJ_ECOFF if (**argP == 'G') { @@ -2983,6 +3023,7 @@ md_parse_option (argP, cntP, vecP) return 1; } #endif + return 1; /* pretend you parsed the character */ } @@ -3356,6 +3397,11 @@ s_mipsset (x) if (strcmp (name, "reorder") == 0) { + if (mips_noreorder) + { + prev_insn_unreordered = 1; + prev_prev_insn_unreordered = 1; + } mips_noreorder = 0; } else if (strcmp (name, "noreorder") == 0) |