|
|
8ae002 |
From 832572eac8a661d25efe0f2bcc6a861e2c29c3b8 Mon Sep 17 00:00:00 2001
|
|
|
8ae002 |
From: Stefan Liebler <stli@linux.vnet.ibm.com>
|
|
|
8ae002 |
Date: Mon, 7 Nov 2016 15:50:46 +0100
|
|
|
8ae002 |
Subject: [PATCH 05/17] S390: Optimize iso-8859-1 to ibm037 iconv-module.
|
|
|
8ae002 |
|
|
|
8ae002 |
Upstream commit 81c6380887c6d62c56e5f0f85a241f759f58b2fd
|
|
|
8ae002 |
|
|
|
8ae002 |
This patch reworks the s390 specific module which used the z900
|
|
|
8ae002 |
translate one to one instruction. Now the g5 translate instruction is used,
|
|
|
8ae002 |
because it outperforms the troo instruction.
|
|
|
8ae002 |
|
|
|
8ae002 |
ChangeLog:
|
|
|
8ae002 |
|
|
|
8ae002 |
* sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c (TROO_LOOP):
|
|
|
8ae002 |
Rename to TR_LOOP and usage of tr instead of troo instruction.
|
|
|
8ae002 |
---
|
|
|
8ae002 |
sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c | 95 +++++++++++++++++-----------
|
|
|
8ae002 |
1 file changed, 57 insertions(+), 38 deletions(-)
|
|
|
8ae002 |
|
|
|
8ae002 |
diff --git a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c b/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c
|
|
|
8ae002 |
index 58641f5..3b63e6a 100644
|
|
|
8ae002 |
--- a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c
|
|
|
8ae002 |
+++ b/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c
|
|
|
8ae002 |
@@ -1,8 +1,7 @@
|
|
|
8ae002 |
/* Conversion between ISO 8859-1 and IBM037.
|
|
|
8ae002 |
|
|
|
8ae002 |
- This module uses the Z900 variant of the Translate One To One
|
|
|
8ae002 |
- instruction.
|
|
|
8ae002 |
- Copyright (C) 1997-2009 Free Software Foundation, Inc.
|
|
|
8ae002 |
+ This module uses the translate instruction.
|
|
|
8ae002 |
+ Copyright (C) 1997-2016 Free Software Foundation, Inc.
|
|
|
8ae002 |
|
|
|
8ae002 |
Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
|
|
8ae002 |
Based on the work by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
|
|
8ae002 |
@@ -176,50 +175,70 @@ __attribute__ ((aligned (8))) =
|
|
|
8ae002 |
#define MIN_NEEDED_FROM 1
|
|
|
8ae002 |
#define MIN_NEEDED_TO 1
|
|
|
8ae002 |
|
|
|
8ae002 |
-/* The Z900 variant of troo forces us to always specify a test
|
|
|
8ae002 |
- character which ends the translation. So if we run into the
|
|
|
8ae002 |
- situation where the translation has been interrupted due to the
|
|
|
8ae002 |
- test character we translate the character by hand and jump back
|
|
|
8ae002 |
- into the instruction. */
|
|
|
8ae002 |
-
|
|
|
8ae002 |
-#define TROO_LOOP(TABLE) \
|
|
|
8ae002 |
+#define TR_LOOP(TABLE) \
|
|
|
8ae002 |
{ \
|
|
|
8ae002 |
- register const unsigned char test asm ("0") = 0; \
|
|
|
8ae002 |
- register const unsigned char *pTable asm ("1") = TABLE; \
|
|
|
8ae002 |
- register unsigned char *pOutput asm ("2") = outptr; \
|
|
|
8ae002 |
- register uint64_t length asm ("3"); \
|
|
|
8ae002 |
- const unsigned char* pInput = inptr; \
|
|
|
8ae002 |
- uint64_t tmp; \
|
|
|
8ae002 |
- \
|
|
|
8ae002 |
- length = (inend - inptr < outend - outptr \
|
|
|
8ae002 |
- ? inend - inptr : outend - outptr); \
|
|
|
8ae002 |
+ size_t length = (inend - inptr < outend - outptr \
|
|
|
8ae002 |
+ ? inend - inptr : outend - outptr); \
|
|
|
8ae002 |
\
|
|
|
8ae002 |
- asm volatile ("0: \n\t" \
|
|
|
8ae002 |
- " troo %0,%1 \n\t" \
|
|
|
8ae002 |
- " jz 1f \n\t" \
|
|
|
8ae002 |
- " jo 0b \n\t" \
|
|
|
8ae002 |
- " llgc %3,0(%1) \n\t" \
|
|
|
8ae002 |
- " la %3,0(%3,%4) \n\t" \
|
|
|
8ae002 |
- " mvc 0(1,%0),0(%3) \n\t" \
|
|
|
8ae002 |
- " aghi %1,1 \n\t" \
|
|
|
8ae002 |
- " aghi %0,1 \n\t" \
|
|
|
8ae002 |
- " aghi %2,-1 \n\t" \
|
|
|
8ae002 |
- " j 0b \n\t" \
|
|
|
8ae002 |
- "1: \n" \
|
|
|
8ae002 |
+ /* Process in 256 byte blocks. */ \
|
|
|
8ae002 |
+ if (__builtin_expect (length >= 256, 0)) \
|
|
|
8ae002 |
+ { \
|
|
|
8ae002 |
+ size_t blocks = length / 256; \
|
|
|
8ae002 |
+ __asm__ __volatile__("0: mvc 0(256,%[R_OUT]),0(%[R_IN])\n\t" \
|
|
|
8ae002 |
+ " tr 0(256,%[R_OUT]),0(%[R_TBL])\n\t" \
|
|
|
8ae002 |
+ " la %[R_IN],256(%[R_IN])\n\t" \
|
|
|
8ae002 |
+ " la %[R_OUT],256(%[R_OUT])\n\t" \
|
|
|
8ae002 |
+ " brctg %[R_LI],0b\n\t" \
|
|
|
8ae002 |
+ : /* outputs */ [R_IN] "+a" (inptr) \
|
|
|
8ae002 |
+ , [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \
|
|
|
8ae002 |
+ : /* inputs */ [R_TBL] "a" (TABLE) \
|
|
|
8ae002 |
+ : /* clobber list */ "memory" \
|
|
|
8ae002 |
+ ); \
|
|
|
8ae002 |
+ length = length % 256; \
|
|
|
8ae002 |
+ } \
|
|
|
8ae002 |
\
|
|
|
8ae002 |
- : "+a" (pOutput), "+a" (pInput), "+d" (length), "=&a" (tmp) \
|
|
|
8ae002 |
- : "a" (pTable), "d" (test) \
|
|
|
8ae002 |
- : "cc"); \
|
|
|
8ae002 |
+ /* Process remaining 0...248 bytes in 8byte blocks. */ \
|
|
|
8ae002 |
+ if (length >= 8) \
|
|
|
8ae002 |
+ { \
|
|
|
8ae002 |
+ size_t blocks = length / 8; \
|
|
|
8ae002 |
+ for (int i = 0; i < blocks; i++) \
|
|
|
8ae002 |
+ { \
|
|
|
8ae002 |
+ outptr[0] = TABLE[inptr[0]]; \
|
|
|
8ae002 |
+ outptr[1] = TABLE[inptr[1]]; \
|
|
|
8ae002 |
+ outptr[2] = TABLE[inptr[2]]; \
|
|
|
8ae002 |
+ outptr[3] = TABLE[inptr[3]]; \
|
|
|
8ae002 |
+ outptr[4] = TABLE[inptr[4]]; \
|
|
|
8ae002 |
+ outptr[5] = TABLE[inptr[5]]; \
|
|
|
8ae002 |
+ outptr[6] = TABLE[inptr[6]]; \
|
|
|
8ae002 |
+ outptr[7] = TABLE[inptr[7]]; \
|
|
|
8ae002 |
+ inptr += 8; \
|
|
|
8ae002 |
+ outptr += 8; \
|
|
|
8ae002 |
+ } \
|
|
|
8ae002 |
+ length = length % 8; \
|
|
|
8ae002 |
+ } \
|
|
|
8ae002 |
\
|
|
|
8ae002 |
- inptr = pInput; \
|
|
|
8ae002 |
- outptr = pOutput; \
|
|
|
8ae002 |
+ /* Process remaining 0...7 bytes. */ \
|
|
|
8ae002 |
+ switch (length) \
|
|
|
8ae002 |
+ { \
|
|
|
8ae002 |
+ case 7: outptr[6] = TABLE[inptr[6]]; \
|
|
|
8ae002 |
+ case 6: outptr[5] = TABLE[inptr[5]]; \
|
|
|
8ae002 |
+ case 5: outptr[4] = TABLE[inptr[4]]; \
|
|
|
8ae002 |
+ case 4: outptr[3] = TABLE[inptr[3]]; \
|
|
|
8ae002 |
+ case 3: outptr[2] = TABLE[inptr[2]]; \
|
|
|
8ae002 |
+ case 2: outptr[1] = TABLE[inptr[1]]; \
|
|
|
8ae002 |
+ case 1: outptr[0] = TABLE[inptr[0]]; \
|
|
|
8ae002 |
+ case 0: break; \
|
|
|
8ae002 |
+ } \
|
|
|
8ae002 |
+ inptr += length; \
|
|
|
8ae002 |
+ outptr += length; \
|
|
|
8ae002 |
}
|
|
|
8ae002 |
|
|
|
8ae002 |
+
|
|
|
8ae002 |
/* First define the conversion function from ISO 8859-1 to CP037. */
|
|
|
8ae002 |
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
|
|
8ae002 |
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
|
|
8ae002 |
#define LOOPFCT FROM_LOOP
|
|
|
8ae002 |
-#define BODY TROO_LOOP (table_iso8859_1_to_cp037)
|
|
|
8ae002 |
+#define BODY TR_LOOP (table_iso8859_1_to_cp037)
|
|
|
8ae002 |
|
|
|
8ae002 |
#include <iconv/loop.c>
|
|
|
8ae002 |
|
|
|
8ae002 |
@@ -228,7 +247,7 @@ __attribute__ ((aligned (8))) =
|
|
|
8ae002 |
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
|
|
8ae002 |
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
|
|
8ae002 |
#define LOOPFCT TO_LOOP
|
|
|
8ae002 |
-#define BODY TROO_LOOP (table_cp037_iso8859_1);
|
|
|
8ae002 |
+#define BODY TR_LOOP (table_cp037_iso8859_1);
|
|
|
8ae002 |
|
|
|
8ae002 |
#include <iconv/loop.c>
|
|
|
8ae002 |
|
|
|
8ae002 |
--
|
|
|
8ae002 |
1.8.3.1
|
|
|
8ae002 |
|