diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2010-07-07 13:33:04 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2010-07-07 06:33:04 -0700 |
commit | 5e86e5405761d9accc2780c524946e29e00b6608 (patch) | |
tree | 8d5cb862e13763d843b42bd088ee3b83d8a7ed95 /gcc/config | |
parent | 0ee95c437f66aaad025b4a46490ef17e32e729ad (diff) | |
download | gcc-5e86e5405761d9accc2780c524946e29e00b6608.zip gcc-5e86e5405761d9accc2780c524946e29e00b6608.tar.gz gcc-5e86e5405761d9accc2780c524946e29e00b6608.tar.bz2 |
Retry rdrand if the carry flag isn't valid.
gcc/
2010-07-07 H.J. Lu <hongjiu.lu@intel.com>
PR target/44844
* config/i386/i386.md (rdrand<mode>): Changed to expand to
retry if the carry flag isn't valid.
(rdrand<mode>_1): New.
gcc/testsuite/
2010-07-07 H.J. Lu <hongjiu.lu@intel.com>
PR target/44844
* gcc.target/i386/rdrand-1.c: Scan "jnc".
* gcc.target/i386/rdrand-2.c: Likewise.
* gcc.target/i386/rdrand-3.c: Likewise.
From-SVN: r161910
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.md | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4170711..12e0579 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -18494,7 +18494,32 @@ [(set_attr "type" "other") (set_attr "prefix_extra" "2")]) -(define_insn "rdrand<mode>" +(define_expand "rdrand<mode>" + [(set (match_operand:SWI248 0 "register_operand" "=r") + (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))] + "TARGET_RDRND" +{ + rtx retry_label, insn, ccc; + + retry_label = gen_label_rtx (); + + emit_label (retry_label); + + /* Generate rdrand. */ + emit_insn (gen_rdrand<mode>_1 (operands[0])); + + /* Retry if the carry flag isn't valid. */ + ccc = gen_rtx_REG (CCCmode, FLAGS_REG); + ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx); + ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx, + gen_rtx_LABEL_REF (VOIDmode, retry_label)); + insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc)); + JUMP_LABEL (insn) = retry_label; + + DONE; +}) + +(define_insn "rdrand<mode>_1" [(set (match_operand:SWI248 0 "register_operand" "=r") (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))] "TARGET_RDRND" |