diff options
author | Jose E. Marchesi <jose.marchesi@oracle.com> | 2016-09-14 07:10:49 -0700 |
---|---|---|
committer | Jose E. Marchesi <jose.marchesi@oracle.com> | 2016-09-14 07:10:49 -0700 |
commit | 46a2d504dd875caf60f9be191a55c9ff676bcd5c (patch) | |
tree | 8cfbcceec843973e7f39e5b7f9d630bb1f4557c3 /gas/config | |
parent | 5d9bbb73c1df68741048c3d0f837b50c289ea608 (diff) | |
download | binutils-gdb-46a2d504dd875caf60f9be191a55c9ff676bcd5c.tar.gz |
gas: detect DCTI couples in sparc
Before SPARC V9 the effect of having a delayed branch instruction in the
delay slot of a conditional delayed branch was undefined.
In SPARC V9 DCTI couples are well defined.
However, starting with the UltraSPARC Architecture 2005, DCTI
couples (of all kind) are deprecated and should not be used, as they may
be slow or behave differently to what the programmer expects.
This patch adds a new command line option --dcti-couples-detect to `as',
disabled by default, that makes the assembler to warn the user if an
unpredictable DCTI couple is found. Tests and documentation are
included.
gas/ChangeLog:
2016-09-14 Jose E. Marchesi <jose.marchesi@oracle.com>
* config/tc-sparc.c (md_assemble): Detect and warning on
unpredictable DCTI couples in certain arches.
(dcti_couples_detect): New global.
(md_longopts): Add command line option -dcti-couples-detect.
(md_show_usage): Document -dcti-couples-detect.
(md_parse_option): Handle OPTION_DCTI_COUPLES_DETECT.
* testsuite/gas/sparc/sparc.exp (gas_64_check): Run
dcti-couples-v8, dcti-couples-v9 and dcti-couples-v9c tests.
* testsuite/gas/sparc/dcti-couples.s: New file.
* testsuite/gas/sparc/dcti-couples-v9c.d: Likewise.
* testsuite/gas/sparc/dcti-couples-v8.d: Likewise.
* testsuite/gas/sparc/dcti-couples-v9.d: Likewise.
* testsuite/gas/sparc/dcti-couples-v9c.l: Likewise.
* testsuite/gas/sparc/dcti-couples-v8.l: Likewise.
* doc/as.texinfo (Overview): Document --dcti-couples-detect.
* doc/c-sparc.texi (Sparc-Opts): Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-sparc.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index fb3e9fe6d5b..2fb3c5ac9e8 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -90,10 +90,15 @@ static int warn_on_bump; architecture, issue a warning. */ static enum sparc_opcode_arch_val warn_after_architecture; -/* Non-zero if as should generate error if an undeclared g[23] register - has been used in -64. */ +/* Non-zero if the assembler should generate error if an undeclared + g[23] register has been used in -64. */ static int no_undeclared_regs; +/* Non-zero if the assembler should generate a warning if an + unpredictable DCTI (delayed control transfer instruction) couple is + found. */ +static int dcti_couples_detect; + /* Non-zero if we should try to relax jumps and calls. */ static int sparc_relax; @@ -484,6 +489,8 @@ struct option md_longopts[] = { {"relax", no_argument, NULL, OPTION_RELAX}, #define OPTION_NO_RELAX (OPTION_MD_BASE + 15) {"no-relax", no_argument, NULL, OPTION_NO_RELAX}, +#define OPTION_DCTI_COUPLES_DETECT (OPTION_MD_BASE + 16) + {"dcti-couples-detect", no_argument, NULL, OPTION_DCTI_COUPLES_DETECT}, {NULL, no_argument, NULL, 0} }; @@ -667,6 +674,10 @@ md_parse_option (int c, const char *arg) sparc_relax = 0; break; + case OPTION_DCTI_COUPLES_DETECT: + dcti_couples_detect = 1; + break; + default: return 0; } @@ -744,6 +755,7 @@ md_show_usage (FILE *stream) appropriate .register directive (default)\n\ -no-undeclared-regs force error on application global register usage\n\ without appropriate .register directive\n\ +--dcti-couples-detect warn when an unpredictable DCTI couple is found\n\ -q ignored\n\ -Qy, -Qn ignored\n\ -s ignored\n")); @@ -1570,16 +1582,38 @@ md_assemble (char *str) if (insn == NULL) return; - /* We warn about attempts to put a floating point branch in a delay slot, - unless the delay slot has been annulled. */ + /* Certain instructions may not appear on delay slots. Check for + these situations. */ if (last_insn != NULL - && (insn->flags & F_FBR) != 0 - && (last_insn->flags & F_DELAYED) != 0 - /* ??? This test isn't completely accurate. We assume anything with - F_{UNBR,CONDBR,FBR} set is annullable. */ - && ((last_insn->flags & (F_UNBR | F_CONDBR | F_FBR)) == 0 - || (last_opcode & ANNUL) == 0)) - as_warn (_("FP branch in delay slot")); + && (last_insn->flags & F_DELAYED) != 0) + { + /* Before SPARC V9 the effect of having a delayed branch + instruction in the delay slot of a conditional delayed branch + was undefined. + + In SPARC V9 DCTI couples are well defined. + + However, starting with the UltraSPARC Architecture 2005, DCTI + couples (of all kind) are deprecated and should not be used, + as they may be slow or behave differently to what the + programmer expects. */ + if (dcti_couples_detect + && (insn->flags & F_DELAYED) != 0 + && ((max_architecture < SPARC_OPCODE_ARCH_V9 + && (last_insn->flags & F_CONDBR) != 0) + || max_architecture >= SPARC_OPCODE_ARCH_V9C)) + as_warn (_("unpredictable DCTI couple")); + + + /* We warn about attempts to put a floating point branch in a + delay slot, unless the delay slot has been annulled. */ + if ((insn->flags & F_FBR) != 0 + /* ??? This test isn't completely accurate. We assume anything with + F_{UNBR,CONDBR,FBR} set is annullable. */ + && ((last_insn->flags & (F_UNBR | F_CONDBR | F_FBR)) == 0 + || (last_opcode & ANNUL) == 0)) + as_warn (_("FP branch in delay slot")); + } /* SPARC before v9 requires a nop instruction between a floating point instruction and a floating point branch. We insert one |