@@ -240,11 +240,63 @@ _hs_text_encode_utf8(uint8_t **destp, const uint16_t *src, size_t srcoff,
240 src += srcoff;
240 src += srcoff;
241 srcend = src + srclen;
241 srcend = src + srclen;
244+#if defined(__x86_64__)
245+ while (srcend - src >= 4) {
246+ uint64_t w = *((uint64_t *) src);
247+ uint16_t a = w & 0xFFFF, b = (w >> 16) & 0xFFFF, c = (w >> 32) & 0xFFFF,
250+ if ((w & 0xFF80FF80FF80FF80ULL) == 0) {
256+ else if ((w & 0xF800F800F800F800ULL) == 0) {
257+ *dest++ = (a >> 6) | 0xC0;
258+ *dest++ = (a & 0x3f) | 0x80;
259+ *dest++ = (b >> 6) | 0xC0;
260+ *dest++ = (b & 0x3f) | 0x80;
261+ *dest++ = (c >> 6) | 0xC0;
262+ *dest++ = (c & 0x3f) | 0x80;
263+ *dest++ = (d >> 6) | 0xC0;
264+ *dest++ = (d & 0x3f) | 0x80;
271+#if defined(__i386__)
272+ while (srcend - src >= 2) {
273+ uint32_t w = *((uint32_t *) src);
274+ uint16_t a = w & 0xFFFF, b = w >> 16;
276+ if ((w & 0xFF80FF80) == 0) {
280+ else if ((w & 0xF800F800) == 0) {
281+ *dest++ = (a >> 6) | 0xC0;
282+ *dest++ = (a & 0x3f) | 0x80;
283+ *dest++ = (b >> 6) | 0xC0;
284+ *dest++ = (b & 0x3f) | 0x80;
243 while (src < srcend) {
291 while (src < srcend) {
244 uint16_t w = *src++;
292 uint16_t w = *src++;
246− if (w <= 0x7F)
294+ if (w <= 0x7F) {
247 *dest++ = w;
295 *dest++ = w;
296+ /* An ASCII byte is likely to begin a run of ASCII bytes.
297+ Falling back into the fast path really helps performance. */
248 else if (w <= 0x7FF) {
300 else if (w <= 0x7FF) {
249 *dest++ = (w >> 6) | 0xC0;
301 *dest++ = (w >> 6) | 0xC0;
250 *dest++ = (w & 0x3f) | 0x80;
302 *dest++ = (w & 0x3f) | 0x80;