diff options
Diffstat (limited to 'sysdeps/alpha/alphaev67')
-rw-r--r-- | sysdeps/alpha/alphaev67/Implies | 1 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/ffs.S | 50 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/ffsll.S | 45 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/rawmemchr.S | 93 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/stpcpy.S | 52 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/stpncpy.S | 116 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/strcat.S | 62 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/strchr.S | 101 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/strlen.S | 61 | ||||
-rw-r--r-- | sysdeps/alpha/alphaev67/strncat.S | 101 |
10 files changed, 682 insertions, 0 deletions
diff --git a/sysdeps/alpha/alphaev67/Implies b/sysdeps/alpha/alphaev67/Implies new file mode 100644 index 0000000000..49d19c4ad8 --- /dev/null +++ b/sysdeps/alpha/alphaev67/Implies @@ -0,0 +1 @@ +alpha/alphaev6 diff --git a/sysdeps/alpha/alphaev67/ffs.S b/sysdeps/alpha/alphaev67/ffs.S new file mode 100644 index 0000000000..a6e887766d --- /dev/null +++ b/sysdeps/alpha/alphaev67/ffs.S @@ -0,0 +1,50 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Finds the first bit set in an integer. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .set noat + + +ENTRY(__ffs) +#ifdef PROF + ldgp gp, 0(pv) + lda AT, _mcount + jsr AT, (AT), _mcount + .prologue 1 +#else + .prologue 0 +#endif + + zap $16, 0xF0, $16 + cttz $16, $0 + addq $0, 1, $0 + cmoveq $16, 0, $0 + + nop + nop + nop + ret + +END(__ffs) + +weak_alias (__ffs, ffs) diff --git a/sysdeps/alpha/alphaev67/ffsll.S b/sysdeps/alpha/alphaev67/ffsll.S new file mode 100644 index 0000000000..b7556496a3 --- /dev/null +++ b/sysdeps/alpha/alphaev67/ffsll.S @@ -0,0 +1,45 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Finds the first bit set in a long. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .set noat + +ENTRY(ffsl) +#ifdef PROF + ldgp gp, 0(pv) + lda AT, _mcount + jsr AT, (AT), _mcount + .prologue 1 +#else + .prologue 0 +#endif + + cttz $16, $0 + addq $0, 1, $0 + cmoveq $16, 0, $0 + ret + +END(ffsl) + +weak_extern (ffsl) +weak_alias (ffsl, ffsll) diff --git a/sysdeps/alpha/alphaev67/rawmemchr.S b/sysdeps/alpha/alphaev67/rawmemchr.S new file mode 100644 index 0000000000..6626ecc892 --- /dev/null +++ b/sysdeps/alpha/alphaev67/rawmemchr.S @@ -0,0 +1,93 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Return pointer to first occurrence of CH in STR. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .set noat + +ENTRY(__rawmemchr) +#ifdef PROF + ldgp gp, 0(pv) + lda AT, _mcount + jsr AT, (AT), _mcount + .prologue 1 +#else + .prologue 0 +#endif + + ldq_u t0, 0(a0) # L : load first quadword Latency=3 + and a1, 0xff, t3 # E : 00000000000000ch + insbl a1, 1, t5 # U : 000000000000ch00 + insbl a1, 7, a2 # U : ch00000000000000 + + insbl t3, 6, a3 # U : 00ch000000000000 + or t5, t3, a1 # E : 000000000000chch + andnot a0, 7, v0 # E : align our loop pointer + lda t4, -1 # E : build garbage mask + + mskqh t4, a0, t4 # U : only want relevant part of first quad + or a2, a3, a2 # E : chch000000000000 + inswl a1, 2, t5 # E : 00000000chch0000 + inswl a1, 4, a3 # E : 0000chch00000000 + + or a1, a2, a1 # E : chch00000000chch + or a3, t5, t5 # E : 0000chchchch0000 + cmpbge zero, t4, t4 # E : bits set iff byte is garbage + nop # E : + + /* This quad is _very_ serialized. Lots of stalling happens */ + or t5, a1, a1 # E : chchchchchchchch + xor t0, a1, t1 # E : make bytes == c zero + cmpbge zero, t1, t0 # E : bits set iff byte == c + andnot t0, t4, t0 # E : clear garbage bits + + cttz t0, a2 # U0 : speculative (in case we get a match) + nop # E : + nop # E : + bne t0, $found # U : + + /* + * Yuk. This loop is going to stall like crazy waiting for the + * data to be loaded. Not much can be done about it unless it's + * unrolled multiple times, which is generally unsafe. + */ +$loop: + ldq t0, 8(v0) # L : Latency=3 + addq v0, 8, v0 # E : + xor t0, a1, t1 # E : + cmpbge zero, t1, t0 # E : bits set iff byte == c + + cttz t0, a2 # U0 : speculative (in case we get a match) + nop # E : + nop # E : + beq t0, $loop # U : + +$found: + negq t0, t1 # E : clear all but least set bit + and t0, t1, t0 # E : + addq v0, a2, v0 # E : Add in the bit number from above + ret # L0 : + + END(__rawmemchr) + +weak_alias (__rawmemchr, rawmemchr) diff --git a/sysdeps/alpha/alphaev67/stpcpy.S b/sysdeps/alpha/alphaev67/stpcpy.S new file mode 100644 index 0000000000..6dcb36659a --- /dev/null +++ b/sysdeps/alpha/alphaev67/stpcpy.S @@ -0,0 +1,52 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@redhat.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Copy SRC to DEST returning the address of the terminating 0 in DEST. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .set noat + .text + +ENTRY(__stpcpy) + ldgp gp, 0(pv) +#ifdef PROF + lda AT, _mcount + jsr AT, (AT), _mcount +#endif + .prologue 1 + + .align 4 + mov a0, v0 + nop + jsr t9, __stxcpy + + # t8 = bitmask (with one bit set) indicating the last byte written + # a0 = unaligned address of the last *word* written + + cttz t8, t8 + andnot a0, 7, a0 + addq a0, t8, v0 + ret + + END(__stpcpy) + +weak_alias (__stpcpy, stpcpy) diff --git a/sysdeps/alpha/alphaev67/stpncpy.S b/sysdeps/alpha/alphaev67/stpncpy.S new file mode 100644 index 0000000000..d648b4db8b --- /dev/null +++ b/sysdeps/alpha/alphaev67/stpncpy.S @@ -0,0 +1,116 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Richard Henderson (rth@redhat.com) + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Copy no more then N bytes from SRC to DEST, returning the address of + the terminating '\0' in DEST. */ + +#include <sysdep.h> + + .arch ev6 + .set noat + .set noreorder + .text + +ENTRY(__stpncpy) + ldgp gp, 0(pv) +#ifdef PROF + lda AT, _mcount + jsr AT, (AT), _mcount +#endif + .prologue 1 + + mov a0, v0 + beq a2, $zerocount + + .align 4 + nop + nop + jsr t9, __stxncpy # do the work of the copy + + cttz t8, t4 + zapnot t0, t8, t5 + andnot a0, 7, a0 + bne a2, $multiword # do we have full words left? + + subq t8, 1, t2 + subq t10, 1, t3 + cmpult zero, t5, t5 + addq a0, t4, v0 + + or t2, t8, t2 + or t3, t10, t3 + addq v0, t5, v0 + andnot t3, t2, t3 + + zap t0, t3, t0 + nop + stq t0, 0(a0) + ret + +$multiword: + subq t8, 1, t7 # clear the final bits in the prev word + cmpult zero, t5, t5 + or t7, t8, t7 + zapnot t0, t7, t0 + + subq a2, 1, a2 + stq t0, 0(a0) + addq a0, 8, a1 + beq a2, 1f # loop over full words remaining + + nop + nop + nop + blbc a2, 0f + + stq zero, 0(a1) + subq a2, 1, a2 + addq a1, 8, a1 + beq a2, 1f + +0: stq zero, 0(a1) + subq a2, 2, a2 + nop + nop + + stq zero, 8(a1) + addq a1, 16, a1 + nop + bne a2, 0b + +1: ldq t0, 0(a1) # clear the leading bits in the final word + subq t10, 1, t7 + addq a0, t4, v0 + nop + + or t7, t10, t7 + addq v0, t5, v0 + zap t0, t7, t0 + stq t0, 0(a1) + +$zerocount: + nop + nop + nop + ret + + END(__stpncpy) + +weak_alias (__stpncpy, stpncpy) diff --git a/sysdeps/alpha/alphaev67/strcat.S b/sysdeps/alpha/alphaev67/strcat.S new file mode 100644 index 0000000000..88e48cec71 --- /dev/null +++ b/sysdeps/alpha/alphaev67/strcat.S @@ -0,0 +1,62 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@tamu.edu>, 1996. + EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Append a null-terminated string from SRC to DST. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .text + +ENTRY(strcat) + ldgp gp, 0(pv) +#ifdef PROF + .set noat + lda AT, _mcount + jsr AT, (AT), _mcount + .set at +#endif + .prologue 1 + + mov $16, $0 # E : set up return value + /* Find the end of the string. */ + ldq_u $1, 0($16) # L : load first quadword (a0 may be misaligned) + lda $2, -1 # E : + insqh $2, $16, $2 # U : + + andnot $16, 7, $16 # E : + or $2, $1, $1 # E : + cmpbge $31, $1, $2 # E : bits set iff byte == 0 + bne $2, $found # U : + +$loop: ldq $1, 8($16) # L : + addq $16, 8, $16 # E : + cmpbge $31, $1, $2 # E : + beq $2, $loop # U : + +$found: cttz $2, $3 # U0 : + addq $16, $3, $16 # E : + /* Now do the append. */ + mov $26, $23 # E : + jmp $31, __stxcpy # L0 : + + END(strcat) diff --git a/sysdeps/alpha/alphaev67/strchr.S b/sysdeps/alpha/alphaev67/strchr.S new file mode 100644 index 0000000000..3ab26556cd --- /dev/null +++ b/sysdeps/alpha/alphaev67/strchr.S @@ -0,0 +1,101 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@tamu.edu>, 1996. + EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Return the address of a given character within a null-terminated + string, or null if it is not found. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .set noat + +ENTRY(strchr) +#ifdef PROF + ldgp gp, 0(pv) + lda AT, _mcount + jsr AT, (AT), _mcount + .prologue 1 +#else + .prologue 0 +#endif + + ldq_u t0, 0(a0) # L : load first quadword Latency=3 + and a1, 0xff, t3 # E : 00000000000000ch + insbl a1, 1, t5 # U : 000000000000ch00 + insbl a1, 7, a2 # U : ch00000000000000 + + insbl t3, 6, a3 # U : 00ch000000000000 + or t5, t3, a1 # E : 000000000000chch + andnot a0, 7, v0 # E : align our loop pointer + lda t4, -1 # E : build garbage mask + + mskqh t4, a0, t4 # U : only want relevant part of first quad + or a2, a3, a2 # E : chch000000000000 + inswl a1, 2, t5 # E : 00000000chch0000 + inswl a1, 4, a3 # E : 0000chch00000000 + + or a1, a2, a1 # E : chch00000000chch + or a3, t5, t5 # E : 0000chchchch0000 + cmpbge zero, t0, t2 # E : bits set iff byte == zero + cmpbge zero, t4, t4 # E : bits set iff byte is garbage + + /* This quad is _very_ serialized. Lots of stalling happens */ + or t5, a1, a1 # E : chchchchchchchch + xor t0, a1, t1 # E : make bytes == c zero + cmpbge zero, t1, t3 # E : bits set iff byte == c + or t2, t3, t0 # E : bits set iff char match or zero match + + andnot t0, t4, t0 # E : clear garbage bits + cttz t0, a2 # U0 : speculative (in case we get a match) + nop # E : + bne t0, $found # U : + + /* + * Yuk. This loop is going to stall like crazy waiting for the + * data to be loaded. Not much can be done about it unless it's + * unrolled multiple times, which is generally unsafe. + */ +$loop: + ldq t0, 8(v0) # L : Latency=3 + addq v0, 8, v0 # E : + xor t0, a1, t1 # E : + cmpbge zero, t0, t2 # E : bits set iff byte == 0 + + cmpbge zero, t1, t3 # E : bits set iff byte == c + or t2, t3, t0 # E : + cttz t3, a2 # U0 : speculative (in case we get a match) + beq t0, $loop # U : + +$found: + negq t0, t1 # E : clear all but least set bit + and t0, t1, t0 # E : + and t0, t3, t1 # E : bit set iff byte was the char + addq v0, a2, v0 # E : Add in the bit number from above + + cmoveq t1, $31, v0 # E : Two mapping slots, latency = 2 + nop + nop + ret # L0 : + + END(strchr) + +weak_alias (strchr, index) diff --git a/sysdeps/alpha/alphaev67/strlen.S b/sysdeps/alpha/alphaev67/strlen.S new file mode 100644 index 0000000000..ac8740fb09 --- /dev/null +++ b/sysdeps/alpha/alphaev67/strlen.S @@ -0,0 +1,61 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Finds length of a 0-terminated string. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .set noat + +ENTRY(strlen) +#ifdef PROF + ldgp gp, 0(pv) + lda AT, _mcount + jsr AT, (AT), _mcount + .prologue 1 +#else + .prologue 0 +#endif + + ldq_u $1, 0($16) # L : load first quadword ($16 may be misaligned) + lda $2, -1($31) # E : + insqh $2, $16, $2 # U : + andnot $16, 7, $0 # E : + + or $2, $1, $1 # E : + cmpbge $31, $1, $2 # E : $2 <- bitmask: bit i == 1 <==> i-th byte == 0 + nop # E : + bne $2, $found # U : + +$loop: ldq $1, 8($0) # L : + addq $0, 8, $0 # E : addr += 8 + cmpbge $31, $1, $2 # E : + beq $2, $loop # U : + +$found: + cttz $2, $3 # U0 : + addq $0, $3, $0 # E : + subq $0, $16, $0 # E : + ret $31, ($26) # L0 : + + END(strlen) diff --git a/sysdeps/alpha/alphaev67/strncat.S b/sysdeps/alpha/alphaev67/strncat.S new file mode 100644 index 0000000000..4d199d95fe --- /dev/null +++ b/sysdeps/alpha/alphaev67/strncat.S @@ -0,0 +1,101 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@tamu.edu>, 1996. + EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Append no more than COUNT characters from the null-terminated string SRC + to the null-terminated string DST. Always null-terminate the new DST. */ + +#include <sysdep.h> + + .arch ev6 + .set noreorder + .text + +ENTRY(strncat) + ldgp gp, 0(pv) +#ifdef PROF + .set noat + lda AT, _mcount + jsr AT, (AT), _mcount + .set at +#endif + .prologue 1 + + mov $16, $0 # set up return value + beq $18, $zerocount # U : + /* Find the end of the string. */ + ldq_u $1, 0($16) # L : load first quadword ($16 may be misaligned) + lda $2, -1($31) # E : + + insqh $2, $0, $2 # U : + andnot $16, 7, $16 # E : + nop # E : + or $2, $1, $1 # E : + + nop # E : + nop # E : + cmpbge $31, $1, $2 # E : bits set iff byte == 0 + bne $2, $found # U : + +$loop: ldq $1, 8($16) # L : + addq $16, 8, $16 # E : + cmpbge $31, $1, $2 # E : + beq $2, $loop # U : + +$found: cttz $2, $3 # U0 : + addq $16, $3, $16 # E : + jsr $23, __stxncpy # L0 :/* Now do the append. */ + + /* Worry about the null termination. */ + + zapnot $1, $27, $2 # U : was last byte a null? + cmplt $27, $24, $5 # E : did we fill the buffer completely? + bne $2, 0f # U : + ret # L0 : + +0: or $5, $18, $2 # E : + nop + bne $2, 2f # U : + and $24, 0x80, $3 # E : no zero next byte + + nop # E : + bne $3, 1f # U : + /* Here there are bytes left in the current word. Clear one. */ + addq $24, $24, $24 # E : end-of-count bit <<= 1 + nop # E : + +2: zap $1, $24, $1 # U : + nop # E : + stq_u $1, 0($16) # L : + ret # L0 : + +1: /* Here we must clear the first byte of the next DST word */ + stb $31, 8($16) # L : + nop # E : + nop # E : + ret # L0 : + +$zerocount: + nop # E : + nop # E : + nop # E : + ret # L0 : + + END(strncat) |