/* A version of the fast scanner using MMX vectorized byte compare insns.
This uses the PMOVMSKB instruction which was introduced with "MMX2",
- which was packaged into SSE1; it is also present in the AMD 3dNOW-A
+ which was packaged into SSE1; it is also present in the AMD MMX
extension. Mark the function as using "sse" so that we emit a real
"emms" instruction, rather than the 3dNOW "femms" instruction. */
return (const uchar *)p + found;
}
+#ifdef HAVE_SSE4
/* A version of the fast scanner using SSE 4.2 vectorized string insns. */
static const uchar *
return s + index;
}
+#else
+/* Work around out-dated assemblers without sse4 support. */
+#define search_line_sse42 search_line_sse2
+#endif
+
/* Check the CPU capabilities. */
#include "../gcc/config/i386/cpuid.h"
minimum = 3;
#elif defined(__SSE2__)
minimum = 2;
-#elif defined(__SSE__) || defined(__3dNOW_A__)
+#elif defined(__SSE__)
minimum = 1;
#endif
}
else if (__get_cpuid (0x80000001, &dummy, &dummy, &dummy, &edx))
{
- if (minimum == 1 || edx & bit_3DNOWP)
+ if (minimum == 1 || (edx & (bit_MMXEXT | bit_CMOV)))
impl = search_line_mmx;
}
search_line_fast = impl;
}
-#elif defined(__GNUC__) && defined(__ALTIVEC__)
+#elif (GCC_VERSION >= 4005) && defined(__ALTIVEC__)
/* A vection of the fast scanner using AltiVec vectorized byte compares. */
/* ??? Unfortunately, attribute(target("altivec")) is not yet supported,
raw_prefix_len) == 0
&& cur[raw_prefix_len+1] == '"')
{
- cur += raw_prefix_len+2;
+ BUF_APPEND (")", 1);
+ base++;
+ cur += raw_prefix_len + 2;
goto break_outer_loop;
}
else
cppchar_t type)
{
unsigned char *buffer;
- unsigned int len, clen;
+ unsigned int len, clen, i;
len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'. */
if (is_vspace (pfile->buffer->cur[-1]))
len--;
- /* If we are currently in a directive, then we need to store all
- C++ comments as C comments internally, and so we need to
- allocate a little extra space in that case.
+ /* If we are currently in a directive or in argument parsing, then
+ we need to store all C++ comments as C comments internally, and
+ so we need to allocate a little extra space in that case.
Note that the only time we encounter a directive here is
when we are saving comments in a "#define". */
- clen = (pfile->state.in_directive && type == '/') ? len + 2 : len;
+ clen = ((pfile->state.in_directive || pfile->state.parsing_args)
+ && type == '/') ? len + 2 : len;
buffer = _cpp_unaligned_alloc (pfile, clen);
memcpy (buffer + 1, from, len - 1);
/* Finish conversion to a C comment, if necessary. */
- if (pfile->state.in_directive && type == '/')
+ if ((pfile->state.in_directive || pfile->state.parsing_args) && type == '/')
{
buffer[1] = '*';
buffer[clen - 2] = '*';
buffer[clen - 1] = '/';
+ /* As there can be in a C++ comments illegal sequences for C comments
+ we need to filter them out. */
+ for (i = 2; i < (clen - 2); i++)
+ if (buffer[i] == '/' && (buffer[i - 1] == '*' || buffer[i + 1] == '*'))
+ buffer[i] = '|';
}
/* Finally store this comment for use by clients of libcpp. */