mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 04:50:07 +00:00
S390: Optimize iso-8859-1 to ibm037 iconv-module.
This patch reworks the s390 specific module which used the z900 translate one to one instruction. Now the g5 translate instruction is used, because it outperforms the troo instruction. ChangeLog: * sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c (TROO_LOOP): Rename to TR_LOOP and usage of tr instead of troo instruction.
This commit is contained in:
parent
3b704e26b3
commit
81c6380887
@ -1,3 +1,8 @@
|
|||||||
|
2016-05-25 Stefan Liebler <stli@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
* sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c (TROO_LOOP):
|
||||||
|
Rename to TR_LOOP and usage of tr instead of troo instruction.
|
||||||
|
|
||||||
2016-05-25 Stefan Liebler <stli@linux.vnet.ibm.com>
|
2016-05-25 Stefan Liebler <stli@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* sysdeps/s390/multiarch/gconv_simple.c: New File.
|
* sysdeps/s390/multiarch/gconv_simple.c: New File.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/* Conversion between ISO 8859-1 and IBM037.
|
/* Conversion between ISO 8859-1 and IBM037.
|
||||||
|
|
||||||
This module uses the Z900 variant of the Translate One To One
|
This module uses the translate instruction.
|
||||||
instruction.
|
|
||||||
Copyright (C) 1997-2016 Free Software Foundation, Inc.
|
Copyright (C) 1997-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
||||||
@ -176,50 +175,70 @@ __attribute__ ((aligned (8))) =
|
|||||||
#define MIN_NEEDED_FROM 1
|
#define MIN_NEEDED_FROM 1
|
||||||
#define MIN_NEEDED_TO 1
|
#define MIN_NEEDED_TO 1
|
||||||
|
|
||||||
/* The Z900 variant of troo forces us to always specify a test
|
#define TR_LOOP(TABLE) \
|
||||||
character which ends the translation. So if we run into the
|
|
||||||
situation where the translation has been interrupted due to the
|
|
||||||
test character we translate the character by hand and jump back
|
|
||||||
into the instruction. */
|
|
||||||
|
|
||||||
#define TROO_LOOP(TABLE) \
|
|
||||||
{ \
|
{ \
|
||||||
register const unsigned char test __asm__ ("0") = 0; \
|
size_t length = (inend - inptr < outend - outptr \
|
||||||
register const unsigned char *pTable __asm__ ("1") = TABLE; \
|
? inend - inptr : outend - outptr); \
|
||||||
register unsigned char *pOutput __asm__ ("2") = outptr; \
|
|
||||||
register uint64_t length __asm__ ("3"); \
|
|
||||||
const unsigned char* pInput = inptr; \
|
|
||||||
uint64_t tmp; \
|
|
||||||
\
|
\
|
||||||
length = (inend - inptr < outend - outptr \
|
/* Process in 256 byte blocks. */ \
|
||||||
? inend - inptr : outend - outptr); \
|
if (__builtin_expect (length >= 256, 0)) \
|
||||||
|
{ \
|
||||||
|
size_t blocks = length / 256; \
|
||||||
|
__asm__ __volatile__("0: mvc 0(256,%[R_OUT]),0(%[R_IN])\n\t" \
|
||||||
|
" tr 0(256,%[R_OUT]),0(%[R_TBL])\n\t" \
|
||||||
|
" la %[R_IN],256(%[R_IN])\n\t" \
|
||||||
|
" la %[R_OUT],256(%[R_OUT])\n\t" \
|
||||||
|
" brctg %[R_LI],0b\n\t" \
|
||||||
|
: /* outputs */ [R_IN] "+a" (inptr) \
|
||||||
|
, [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \
|
||||||
|
: /* inputs */ [R_TBL] "a" (TABLE) \
|
||||||
|
: /* clobber list */ "memory" \
|
||||||
|
); \
|
||||||
|
length = length % 256; \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
__asm__ volatile ("0: \n\t" \
|
/* Process remaining 0...248 bytes in 8byte blocks. */ \
|
||||||
" troo %0,%1 \n\t" \
|
if (length >= 8) \
|
||||||
" jz 1f \n\t" \
|
{ \
|
||||||
" jo 0b \n\t" \
|
size_t blocks = length / 8; \
|
||||||
" llgc %3,0(%1) \n\t" \
|
for (int i = 0; i < blocks; i++) \
|
||||||
" la %3,0(%3,%4) \n\t" \
|
{ \
|
||||||
" mvc 0(1,%0),0(%3) \n\t" \
|
outptr[0] = TABLE[inptr[0]]; \
|
||||||
" aghi %1,1 \n\t" \
|
outptr[1] = TABLE[inptr[1]]; \
|
||||||
" aghi %0,1 \n\t" \
|
outptr[2] = TABLE[inptr[2]]; \
|
||||||
" aghi %2,-1 \n\t" \
|
outptr[3] = TABLE[inptr[3]]; \
|
||||||
" j 0b \n\t" \
|
outptr[4] = TABLE[inptr[4]]; \
|
||||||
"1: \n" \
|
outptr[5] = TABLE[inptr[5]]; \
|
||||||
|
outptr[6] = TABLE[inptr[6]]; \
|
||||||
|
outptr[7] = TABLE[inptr[7]]; \
|
||||||
|
inptr += 8; \
|
||||||
|
outptr += 8; \
|
||||||
|
} \
|
||||||
|
length = length % 8; \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
: "+a" (pOutput), "+a" (pInput), "+d" (length), "=&a" (tmp) \
|
/* Process remaining 0...7 bytes. */ \
|
||||||
: "a" (pTable), "d" (test) \
|
switch (length) \
|
||||||
: "cc"); \
|
{ \
|
||||||
\
|
case 7: outptr[6] = TABLE[inptr[6]]; \
|
||||||
inptr = pInput; \
|
case 6: outptr[5] = TABLE[inptr[5]]; \
|
||||||
outptr = pOutput; \
|
case 5: outptr[4] = TABLE[inptr[4]]; \
|
||||||
|
case 4: outptr[3] = TABLE[inptr[3]]; \
|
||||||
|
case 3: outptr[2] = TABLE[inptr[2]]; \
|
||||||
|
case 2: outptr[1] = TABLE[inptr[1]]; \
|
||||||
|
case 1: outptr[0] = TABLE[inptr[0]]; \
|
||||||
|
case 0: break; \
|
||||||
|
} \
|
||||||
|
inptr += length; \
|
||||||
|
outptr += length; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* First define the conversion function from ISO 8859-1 to CP037. */
|
/* First define the conversion function from ISO 8859-1 to CP037. */
|
||||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||||
#define LOOPFCT FROM_LOOP
|
#define LOOPFCT FROM_LOOP
|
||||||
#define BODY TROO_LOOP (table_iso8859_1_to_cp037)
|
#define BODY TR_LOOP (table_iso8859_1_to_cp037)
|
||||||
|
|
||||||
#include <iconv/loop.c>
|
#include <iconv/loop.c>
|
||||||
|
|
||||||
@ -228,7 +247,7 @@ __attribute__ ((aligned (8))) =
|
|||||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||||
#define LOOPFCT TO_LOOP
|
#define LOOPFCT TO_LOOP
|
||||||
#define BODY TROO_LOOP (table_cp037_iso8859_1);
|
#define BODY TR_LOOP (table_cp037_iso8859_1);
|
||||||
|
|
||||||
#include <iconv/loop.c>
|
#include <iconv/loop.c>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user