aboutsummaryrefslogtreecommitdiff
path: root/libcpp/lex.c
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2015-06-30 10:26:57 +0200
committerUros Bizjak <uros@gcc.gnu.org>2015-06-30 10:26:57 +0200
commitdc6bcf52ebcc487d78060c22df62367732370881 (patch)
tree3e649d9c12df346a13be8355f1c9a4a10b867abe /libcpp/lex.c
parent7e6a6f0d6e48c84fa704f11e94ee8db207afd01e (diff)
lex.c (search_line_sse42): New main loop using asm flag outputs.
* lex.c (search_line_sse42) [__GCC_ASM_FLAG_OUTPUTS__]: New main loop using asm flag outputs. From-SVN: r225160
Diffstat (limited to 'libcpp/lex.c')
-rw-r--r--libcpp/lex.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/libcpp/lex.c b/libcpp/lex.c
index c7296a110b6..5758e580c2b 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -450,15 +450,33 @@ search_line_sse42 (const uchar *s, const uchar *end)
s = (const uchar *)((si + 16) & -16);
}
- /* Main loop, processing 16 bytes at a time. By doing the whole loop
- in inline assembly, we can make proper use of the flags set. */
- __asm ( "sub $16, %1\n"
- " .balign 16\n"
+ /* Main loop, processing 16 bytes at a time. */
+#ifdef __GCC_ASM_FLAG_OUTPUTS__
+ while (1)
+ {
+ char f;
+
+ /* By using inline assembly instead of the builtin,
+ we can use the result, as well as the flags set. */
+ __asm ("%vpcmpestri\t$0, %2, %3"
+ : "=c"(index), "=@ccc"(f)
+ : "m"(*s), "x"(search), "a"(4), "d"(16));
+ if (f)
+ break;
+
+ s += 16;
+ }
+#else
+ s -= 16;
+ /* By doing the whole loop in inline assembly,
+ we can make proper use of the flags set. */
+ __asm ( ".balign 16\n"
"0: add $16, %1\n"
- " %vpcmpestri $0, (%1), %2\n"
+ " %vpcmpestri\t$0, (%1), %2\n"
" jnc 0b"
: "=&c"(index), "+r"(s)
: "x"(search), "a"(4), "d"(16));
+#endif
found:
return s + index;