aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 20:26:19 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 20:26:19 +0000
commita720bafb9f51bb5f669f51ed0857a07134733e9a (patch)
tree214a76a76c5aa792f775d4084f66c8c96070ca28
parent9cb1d07b6fcdddf5a47e04150189ba54fa3f590e (diff)
parent0cb9739fdecbc11df2456807d8de81517b957a29 (diff)
downloadarm-optimized-routines-a720bafb9f51bb5f669f51ed0857a07134733e9a.tar.gz
Change-Id: Ic5b8b358ec673b47b1b6d01270834a52c1b3c178
-rwxr-xr-xAndroid.bp36
-rw-r--r--LICENSE2
-rw-r--r--METADATA6
-rw-r--r--Makefile87
-rw-r--r--README17
-rw-r--r--README.version2
-rwxr-xr-xauxiliary/remez.jl (renamed from math/tools/remez.jl)0
-rw-r--r--config.mk.dist6
-rw-r--r--math/Dir.mk97
-rw-r--r--math/cosf.c6
-rw-r--r--math/exp.c4
-rw-r--r--math/exp2.c4
-rw-r--r--math/expf.c5
-rw-r--r--math/funder.c3
-rw-r--r--math/include/mathlib.h3
-rw-r--r--math/log.c4
-rw-r--r--math/log2.c4
-rw-r--r--math/logf.c5
-rw-r--r--math/logf_data.c3
-rw-r--r--math/pow.c4
-rw-r--r--math/powf.c5
-rw-r--r--math/powf_log2_data.c3
-rw-r--r--math/rem_pio2.c1
-rw-r--r--math/rredf.c3
-rw-r--r--math/sincosf.c6
-rw-r--r--math/sincosf_data.c4
-rw-r--r--math/sinf.c6
-rw-r--r--math/single/dunder.c52
-rw-r--r--math/single/e_expf.c117
-rw-r--r--math/single/e_logf.c153
-rw-r--r--math/single/e_powf.c658
-rw-r--r--math/single/e_rem_pio2.c268
-rw-r--r--math/single/funder.c51
-rw-r--r--math/single/ieee_status.c38
-rw-r--r--math/single/math_private.h138
-rw-r--r--math/single/poly.c25
-rw-r--r--math/single/rredf.c239
-rw-r--r--math/single/rredf.h146
-rw-r--r--math/single/s_cosf.c11
-rw-r--r--math/single/s_sincosf.c109
-rw-r--r--math/single/s_sinf.c11
-rw-r--r--math/single/s_tanf.c77
-rw-r--r--math/tanf.c3
-rwxr-xr-xmath/test/runulp.sh85
-rw-r--r--math/test/ulp.c714
-rw-r--r--math/test/ulp.h338
-rw-r--r--math/tools/cos.sollya31
-rw-r--r--math/tools/exp.sollya35
-rw-r--r--math/tools/exp2.sollya48
-rw-r--r--math/tools/log.sollya35
-rw-r--r--math/tools/log2.sollya42
-rw-r--r--math/tools/log2_abs.sollya41
-rw-r--r--math/tools/log_abs.sollya35
-rwxr-xr-xmath/tools/plot.py56
-rw-r--r--math/tools/sin.sollya37
-rw-r--r--string/Dir.mk75
-rw-r--r--string/aarch64/memchr-sve.S62
-rw-r--r--string/aarch64/memchr.S149
-rw-r--r--string/aarch64/memcmp-sve.S48
-rw-r--r--string/aarch64/memcmp.S141
-rw-r--r--string/aarch64/memcpy.S178
-rw-r--r--string/aarch64/memmove.S103
-rw-r--r--string/aarch64/memset.S188
-rw-r--r--string/aarch64/strchr-sve.S69
-rw-r--r--string/aarch64/strchr.S137
-rw-r--r--string/aarch64/strchrnul-sve.S9
-rw-r--r--string/aarch64/strchrnul.S122
-rw-r--r--string/aarch64/strcmp-sve.S57
-rw-r--r--string/aarch64/strcmp.S177
-rw-r--r--string/aarch64/strcpy-sve.S69
-rw-r--r--string/aarch64/strcpy.S314
-rw-r--r--string/aarch64/strlen-sve.S55
-rw-r--r--string/aarch64/strlen.S214
-rw-r--r--string/aarch64/strncmp-sve.S66
-rw-r--r--string/aarch64/strncmp.S266
-rw-r--r--string/aarch64/strnlen-sve.S72
-rw-r--r--string/aarch64/strnlen.S160
-rw-r--r--string/aarch64/strrchr-sve.S83
-rw-r--r--string/arm/memchr.S133
-rw-r--r--string/arm/memcpy.S593
-rw-r--r--string/arm/memset.S99
-rw-r--r--string/arm/strcmp-armv6m.S118
-rw-r--r--string/arm/strcmp.S479
-rw-r--r--string/arm/strcpy.c129
-rw-r--r--string/arm/strlen-armv6t2.S125
-rw-r--r--string/asmdefs.h17
-rw-r--r--string/include/stringlib.h49
-rw-r--r--string/memchr.S15
-rw-r--r--string/memcmp.S13
-rw-r--r--string/memcpy.S12
-rw-r--r--string/memcpy_bytewise.S23
-rw-r--r--string/memmove.S10
-rw-r--r--string/memset.S12
-rw-r--r--string/strchr.S13
-rw-r--r--string/strchrnul.S13
-rw-r--r--string/strcmp.S19
-rw-r--r--string/strcpy-c.c10
-rw-r--r--string/strcpy.S13
-rw-r--r--string/strlen.S17
-rw-r--r--string/strncmp.S13
-rw-r--r--string/strnlen.S13
-rw-r--r--string/strrchr.S12
-rw-r--r--string/test/memchr.c94
-rw-r--r--string/test/memcmp.c97
-rw-r--r--string/test/memcpy.c97
-rw-r--r--string/test/memmove.c142
-rw-r--r--string/test/memset.c112
-rw-r--r--string/test/strchr.c98
-rw-r--r--string/test/strchrnul.c100
-rw-r--r--string/test/strcmp.c104
-rw-r--r--string/test/strcpy.c100
-rw-r--r--string/test/strlen.c91
-rw-r--r--string/test/strncmp.c104
-rw-r--r--string/test/strnlen.c94
-rw-r--r--string/test/strrchr.c97
-rw-r--r--test/mathbench.c (renamed from math/test/mathbench.c)0
-rw-r--r--test/mathtest.c (renamed from math/test/mathtest.c)3
-rw-r--r--test/rtest/dotest.c (renamed from math/test/rtest/dotest.c)0
-rw-r--r--test/rtest/intern.h (renamed from math/test/rtest/intern.h)0
-rw-r--r--test/rtest/main.c (renamed from math/test/rtest/main.c)0
-rw-r--r--test/rtest/random.c (renamed from math/test/rtest/random.c)0
-rw-r--r--test/rtest/random.h (renamed from math/test/rtest/random.h)0
-rw-r--r--test/rtest/semi.c (renamed from math/test/rtest/semi.c)0
-rw-r--r--test/rtest/semi.h (renamed from math/test/rtest/semi.h)0
-rw-r--r--test/rtest/types.h (renamed from math/test/rtest/types.h)0
-rw-r--r--test/rtest/wrappers.c (renamed from math/test/rtest/wrappers.c)0
-rw-r--r--test/rtest/wrappers.h (renamed from math/test/rtest/wrappers.h)0
-rw-r--r--test/testcases/directed/cosf.tst (renamed from math/test/testcases/directed/cosf.tst)0
-rw-r--r--test/testcases/directed/exp.tst (renamed from math/test/testcases/directed/exp.tst)0
-rw-r--r--test/testcases/directed/exp2.tst (renamed from math/test/testcases/directed/exp2.tst)0
-rw-r--r--test/testcases/directed/exp2f.tst (renamed from math/test/testcases/directed/exp2f.tst)0
-rw-r--r--test/testcases/directed/expf.tst (renamed from math/test/testcases/directed/expf.tst)0
-rw-r--r--test/testcases/directed/log.tst (renamed from math/test/testcases/directed/log.tst)0
-rw-r--r--test/testcases/directed/log2.tst (renamed from math/test/testcases/directed/log2.tst)0
-rw-r--r--test/testcases/directed/log2f.tst (renamed from math/test/testcases/directed/log2f.tst)0
-rw-r--r--test/testcases/directed/logf.tst (renamed from math/test/testcases/directed/logf.tst)0
-rw-r--r--test/testcases/directed/pow.tst (renamed from math/test/testcases/directed/pow.tst)0
-rw-r--r--test/testcases/directed/powf.tst (renamed from math/test/testcases/directed/powf.tst)0
-rw-r--r--test/testcases/directed/rred.tst96
-rw-r--r--test/testcases/directed/rred2.tst516
-rw-r--r--test/testcases/directed/rred3.tst505
-rw-r--r--test/testcases/directed/rred4.tst504
-rw-r--r--test/testcases/directed/rred5.tst563
-rw-r--r--test/testcases/directed/sincosf.tst (renamed from math/test/testcases/directed/sincosf.tst)0
-rw-r--r--test/testcases/directed/sinf.tst (renamed from math/test/testcases/directed/sinf.tst)0
-rw-r--r--test/testcases/random/double.tst (renamed from math/test/testcases/random/double.tst)1
-rw-r--r--test/testcases/random/float.tst (renamed from math/test/testcases/random/float.tst)0
-rw-r--r--test/traces/exp.txt (renamed from math/test/traces/exp.txt)0
-rw-r--r--test/traces/sincosf.txt (renamed from math/test/traces/sincosf.txt)0
149 files changed, 4452 insertions, 7749 deletions
diff --git a/Android.bp b/Android.bp
index b0612a8..2276161 100755
--- a/Android.bp
+++ b/Android.bp
@@ -2,22 +2,39 @@ cc_library {
name: "libarm-optimized-routines",
host_supported: true,
recovery_available: true,
- native_bridge_supported: true,
cflags: [
"-Werror",
- "-Wno-unused-parameter",
"-O2",
- // We're actually implementing bionic here, so we don't want <math.h>
- // to try to be helpful by renaming long double routines.
- "-D__BIONIC_LP32_USE_LONG_DOUBLE",
"-DWANT_ROUNDING=0",
"-DWANT_ERRNO=0",
"-DFLT_EVAL_METHOD=0",
"-ffp-contract=fast",
],
- local_include_dirs: ["math/include"],
srcs: [
- "math/*.c",
+ "math/cosf.c",
+ "math/exp2.c",
+ "math/exp2f.c",
+ "math/exp2f_data.c",
+ "math/exp.c",
+ "math/exp_data.c",
+ "math/expf.c",
+ "math/log2.c",
+ "math/log2_data.c",
+ "math/log2f.c",
+ "math/log2f_data.c",
+ "math/log.c",
+ "math/log_data.c",
+ "math/logf.c",
+ "math/logf_data.c",
+ "math/math_err.c",
+ "math/math_errf.c",
+ "math/pow.c",
+ "math/pow_log_data.c",
+ "math/powf.c",
+ "math/powf_log2_data.c",
+ "math/sincosf.c",
+ "math/sincosf_data.c",
+ "math/sinf.c",
],
// arch-specific settings
@@ -51,9 +68,10 @@ cc_test {
host_supported: true,
cflags: ["-Werror", "-Wno-missing-braces"],
srcs: [
- "math/test/mathtest.c"
+ "math/single/e_rem_pio2.c",
+ "test/mathtest.c"
],
- data: ["math/test/testcases/directed/*.tst"],
+ data: ["test/testcases/directed/*.tst"],
local_include_dirs: ["math/include"],
target: {
darwin: {
diff --git a/LICENSE b/LICENSE
index 2543b82..453ae10 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 1999-2019, Arm Limited.
+Copyright (c) 1999-2018, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/METADATA b/METADATA
index 9762f4f..e63c7e7 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/ARM-software/optimized-routines.git"
}
- version: "9c8399909a9835e6f55977df1661cf6306c56707"
+ version: "6e60567b9bbf59b38c72493faf7cc9eb6ce43c64"
license_type: NOTICE
last_upgrade_date {
year: 2019
- month: 9
- day: 3
+ month: 1
+ day: 8
}
}
diff --git a/Makefile b/Makefile
index 8305684..f5b5d3b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
# Makefile - requires GNU make
#
-# Copyright (c) 2018-2019, Arm Limited.
+# Copyright (c) 2018, Arm Limited.
# SPDX-License-Identifier: MIT
srcdir = .
@@ -9,38 +9,55 @@ bindir = $(prefix)/bin
libdir = $(prefix)/lib
includedir = $(prefix)/include
-# Build targets
-ALL_OBJS = $(math-objs) $(string-objs)
-ALL_INCLUDES = $(math-includes) $(string-includes)
-ALL_LIBS = $(math-libs) $(string-libs)
-ALL_TOOLS = $(math-tools) $(string-tools)
-HOST_TOOLS = $(math-host-tools)
+MATH_SRCS = $(wildcard $(srcdir)/math/*.[cS])
+MATH_BASE = $(basename $(MATH_SRCS))
+MATH_OBJS = $(MATH_BASE:$(srcdir)/%=build/%.o)
+RTEST_SRCS = $(wildcard $(srcdir)/test/rtest/*.[cS])
+RTEST_BASE = $(basename $(RTEST_SRCS))
+RTEST_OBJS = $(RTEST_BASE:$(srcdir)/%=build/%.o)
+ALL_OBJS = $(MATH_OBJS) \
+ $(RTEST_OBJS) \
+ build/test/mathtest.o \
+ build/test/mathbench.o \
+
+INCLUDES = $(wildcard $(srcdir)/math/include/*.h)
+ALL_INCLUDES = $(INCLUDES:$(srcdir)/math/%=build/%)
+
+ALL_LIBS = \
+ build/lib/libmathlib.so \
+ build/lib/libmathlib.a \
+
+ALL_TOOLS = \
+ build/bin/mathtest \
+ build/bin/mathbench \
+ build/bin/mathbench_libc \
+
+HOST_TOOLS = \
+ build/bin/rtest \
+
+TESTS = $(wildcard $(srcdir)/test/testcases/directed/*.tst)
+RTESTS = $(wildcard $(srcdir)/test/testcases/random/*.tst)
# Configure these in config.mk, do not make changes in this file.
HOST_CC = cc
HOST_CFLAGS = -std=c99 -O2
HOST_LDFLAGS =
-HOST_LDLIBS =
+HOST_LDLIBS = -lm -lmpfr -lmpc
EMULATOR =
CFLAGS = -std=c99 -O2
LDFLAGS =
-LDLIBS =
+LDLIBS = -lm
CPPFLAGS =
AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib
INSTALL = install
-CFLAGS_ALL = -Ibuild/include $(CPPFLAGS) $(CFLAGS)
+CFLAGS_ALL = -I$(srcdir)/math/include $(CPPFLAGS) $(CFLAGS)
LDFLAGS_ALL = $(LDFLAGS)
-all:
-
-include config.mk
-include math/Dir.mk
-include string/Dir.mk
-
-all: all-math all-string
+all: $(ALL_LIBS) $(ALL_TOOLS) $(ALL_INCLUDES)
DIRS = $(dir $(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(ALL_INCLUDES))
ALL_DIRS = $(sort $(DIRS:%/=%))
@@ -52,6 +69,11 @@ $(ALL_DIRS):
$(ALL_OBJS:%.o=%.os): CFLAGS_ALL += -fPIC
+$(RTEST_OBJS): CC = $(HOST_CC)
+$(RTEST_OBJS): CFLAGS_ALL = $(HOST_CFLAGS)
+
+build/test/mathtest.o: CFLAGS_ALL += -fmath-errno
+
build/%.o: $(srcdir)/%.S
$(CC) $(CFLAGS_ALL) -c -o $@ $<
@@ -64,6 +86,29 @@ build/%.os: $(srcdir)/%.S
build/%.os: $(srcdir)/%.c
$(CC) $(CFLAGS_ALL) -c -o $@ $<
+build/lib/libmathlib.so: $(MATH_OBJS:%.o=%.os)
+ $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -shared -o $@ $^
+
+build/lib/libmathlib.a: $(MATH_OBJS)
+ rm -f $@
+ $(AR) rc $@ $^
+ $(RANLIB) $@
+
+build/bin/rtest: $(RTEST_OBJS)
+ $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(HOST_LDLIBS)
+
+build/bin/mathtest: build/test/mathtest.o build/lib/libmathlib.a
+ $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
+
+build/bin/mathbench: build/test/mathbench.o build/lib/libmathlib.a
+ $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
+
+build/bin/mathbench_libc: build/test/mathbench.o
+ $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
+
+build/include/%.h: $(srcdir)/math/include/%.h
+ cp $< $@
+
clean:
rm -rf build
@@ -90,6 +135,12 @@ install-headers: $(ALL_INCLUDES:build/include/%=$(DESTDIR)$(includedir)/%)
install: install-libs install-headers
-check: check-math check-string
+check: $(ALL_TOOLS)
+ cat $(TESTS) | $(EMULATOR) build/bin/mathtest
+
+rcheck: $(HOST_TOOLS) $(ALL_TOOLS)
+ cat $(RTESTS) | build/bin/rtest | $(EMULATOR) build/bin/mathtest
+
+check-all: check rcheck
-.PHONY: all clean distclean install install-tools install-libs install-headers check
+.PHONY: all clean distclean install install-tools install-libs install-headers check rcheck check-all
diff --git a/README b/README
index f0345ba..7c6811b 100644
--- a/README
+++ b/README
@@ -8,16 +8,16 @@ relicensing and copyright assignment to the FSF is possible later).
Source code layout:
+auxiliary/ - design tools.
build/ - build directory (created by make).
-math/ - math subproject sources.
+math/ - math library source.
math/include/ - math library public headers.
-math/test/ - math test and benchmark related sources.
-math/tools/ - tools used for designing the algorithms.
-string/ - string routines subproject sources.
-string/include/ - string library public headers.
-string/test/ - string test and benchmark related sources.
+math/single/ - code for cpu with only single precision support.
+test/ - test related source.
+test/rtest/ - test generator (requires mpfr and mpc).
+test/testcases/ - test cases.
-The steps to build the target libraries and run the tests:
+The steps to build the library and run the tests:
cp config.mk.dist config.mk
# edit config.mk if necessary ...
@@ -38,3 +38,6 @@ The test system requires libmpfr and libmpc.
For cross build, CROSS_COMPILE should be set in config.mk and EMULATOR
should be set for cross testing (e.g. using qemu-user or remote access
to a target machine), see the examples in config.mk.dist.
+
+The script "remez.jl" was used to generate some of the coefficients
+(see comments in the code).
diff --git a/README.version b/README.version
new file mode 100644
index 0000000..856bfd9
--- /dev/null
+++ b/README.version
@@ -0,0 +1,2 @@
+URL: https://github.com/ARM-software/optimized-routines.git
+BugComponent: 14890
diff --git a/math/tools/remez.jl b/auxiliary/remez.jl
index f479fc5..f479fc5 100755
--- a/math/tools/remez.jl
+++ b/auxiliary/remez.jl
diff --git a/config.mk.dist b/config.mk.dist
index 36f67d8..7cf7393 100644
--- a/config.mk.dist
+++ b/config.mk.dist
@@ -15,15 +15,15 @@ CFLAGS += -Wall -Wno-missing-braces
HOST_CFLAGS += -g
CFLAGS += -g
-# Use if mpfr is available on the target for ulp error checking.
-#LDLIBS += -lmpfr -lgmp
-#CFLAGS += -DUSE_MPFR
+# Use if the target FPU only supports single precision.
+#CFLAGS += WANT_SINGLEPREC
# Use with gcc.
CFLAGS += -frounding-math -fexcess-precision=standard -fno-stack-protector
CFLAGS += -ffp-contract=fast -fno-math-errno
# Use with clang.
+#CFLAGS += -DCLANG_EXCEPTIONS
#CFLAGS += -ffp-contract=fast
# Use for cross compilation with gcc.
diff --git a/math/Dir.mk b/math/Dir.mk
deleted file mode 100644
index 131f82a..0000000
--- a/math/Dir.mk
+++ /dev/null
@@ -1,97 +0,0 @@
-# Makefile fragment - requires GNU make
-#
-# Copyright (c) 2019, Arm Limited.
-# SPDX-License-Identifier: MIT
-
-math-lib-srcs := $(wildcard $(srcdir)/math/*.[cS])
-math-test-srcs := \
- $(srcdir)/math/test/mathtest.c \
- $(srcdir)/math/test/mathbench.c \
- $(srcdir)/math/test/ulp.c \
-
-math-test-host-srcs := $(wildcard $(srcdir)/math/test/rtest/*.[cS])
-math-includes-src := $(wildcard $(srcdir)/math/include/*.h)
-math-includes := $(math-includes-src:$(srcdir)/math/%=build/%)
-
-math-libs := \
- build/lib/libmathlib.so \
- build/lib/libmathlib.a \
-
-math-tools := \
- build/bin/mathtest \
- build/bin/mathbench \
- build/bin/mathbench_libc \
- build/bin/runulp.sh \
- build/bin/ulp \
-
-math-host-tools := \
- build/bin/rtest \
-
-math-lib-base := $(basename $(math-lib-srcs))
-math-lib-objs := $(math-lib-base:$(srcdir)/%=build/%.o)
-math-test-base := $(basename $(math-test-srcs))
-math-test-objs := $(math-test-base:$(srcdir)/%=build/%.o)
-math-test-host-base := $(basename $(math-test-host-srcs))
-math-test-host-objs := $(math-test-host-base:$(srcdir)/%=build/%.o)
-
-math-objs := \
- $(math-lib-objs) \
- $(math-test-objs) \
- $(math-test-host-objs) \
-
-all-math: $(math-libs) $(math-tools) $(math-includes)
-
-TESTS = $(wildcard $(srcdir)/math/test/testcases/directed/*.tst)
-RTESTS = $(wildcard $(srcdir)/math/test/testcases/random/*.tst)
-
-$(math-objs) $(math-objs:%.o=%.os): $(math-includes)
-build/math/test/mathtest.o: CFLAGS_ALL += -fmath-errno
-$(math-test-host-objs): CC = $(HOST_CC)
-$(math-test-host-objs): CFLAGS_ALL = $(HOST_CFLAGS)
-
-build/math/test/ulp.o: $(srcdir)/math/test/ulp.h
-
-build/lib/libmathlib.so: $(math-lib-objs:%.o=%.os)
- $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -shared -o $@ $^
-
-build/lib/libmathlib.a: $(math-lib-objs)
- rm -f $@
- $(AR) rc $@ $^
- $(RANLIB) $@
-
-$(math-host-tools): HOST_LDLIBS += -lm -lmpfr -lmpc
-$(math-tools): LDLIBS += -lm
-
-build/bin/rtest: $(math-test-host-objs)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(HOST_LDLIBS)
-
-build/bin/mathtest: build/math/test/mathtest.o build/lib/libmathlib.a
- $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
-
-build/bin/mathbench: build/math/test/mathbench.o build/lib/libmathlib.a
- $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
-
-build/bin/mathbench_libc: build/math/test/mathbench.o
- $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
-
-build/bin/ulp: build/math/test/ulp.o build/lib/libmathlib.a
- $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
-
-build/include/%.h: $(srcdir)/math/include/%.h
- cp $< $@
-
-build/bin/%.sh: $(srcdir)/math/test/%.sh
- cp $< $@
-
-check-math-test: $(math-tools)
- cat $(TESTS) | $(EMULATOR) build/bin/mathtest
-
-check-math-rtest: $(math-host-tools) $(math-tools)
- cat $(RTESTS) | build/bin/rtest | $(EMULATOR) build/bin/mathtest
-
-check-math-ulp: $(math-tools)
- build/bin/runulp.sh $(EMULATOR)
-
-check-math: check-math-test check-math-rtest check-math-ulp
-
-.PHONY: all-math check-math-test check-math-rtest check-math-ulp check-math
diff --git a/math/cosf.c b/math/cosf.c
index 831b39e..84a138f 100644
--- a/math/cosf.c
+++ b/math/cosf.c
@@ -5,6 +5,10 @@
* SPDX-License-Identifier: MIT
*/
+#if WANT_SINGLEPREC
+#include "single/s_cosf.c"
+#else
+
#include <stdint.h>
#include <math.h>
#include "math_config.h"
@@ -61,3 +65,5 @@ cosf (float y)
else
return __math_invalidf (y);
}
+
+#endif
diff --git a/math/exp.c b/math/exp.c
index 1909b8e..ffd3111 100644
--- a/math/exp.c
+++ b/math/exp.c
@@ -5,7 +5,6 @@
* SPDX-License-Identifier: MIT
*/
-#include <float.h>
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -170,7 +169,4 @@ __exp_dd (double x, double xtail)
strong_alias (exp, __exp_finite)
hidden_alias (exp, __ieee754_exp)
hidden_alias (__exp_dd, __exp1)
-# if LDBL_MANT_DIG == 53
-long double expl (long double x) { return exp (x); }
-# endif
#endif
diff --git a/math/exp2.c b/math/exp2.c
index 47aa479..fbedbcb 100644
--- a/math/exp2.c
+++ b/math/exp2.c
@@ -5,7 +5,6 @@
* SPDX-License-Identifier: MIT
*/
-#include <float.h>
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -137,7 +136,4 @@ exp2 (double x)
#if USE_GLIBC_ABI
strong_alias (exp2, __exp2_finite)
hidden_alias (exp2, __ieee754_exp2)
-# if LDBL_MANT_DIG == 53
-long double exp2l (long double x) { return exp2 (x); }
-# endif
#endif
diff --git a/math/expf.c b/math/expf.c
index 0fe1f7d..f8238a7 100644
--- a/math/expf.c
+++ b/math/expf.c
@@ -5,6 +5,10 @@
* SPDX-License-Identifier: MIT
*/
+#if WANT_SINGLEPREC
+#include "single/e_expf.c"
+#else
+
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -89,3 +93,4 @@ expf (float x)
strong_alias (expf, __expf_finite)
hidden_alias (expf, __ieee754_expf)
#endif
+#endif
diff --git a/math/funder.c b/math/funder.c
new file mode 100644
index 0000000..14fdd2e
--- /dev/null
+++ b/math/funder.c
@@ -0,0 +1,3 @@
+#if WANT_SINGLEPREC
+#include "single/funder.c"
+#endif
diff --git a/math/include/mathlib.h b/math/include/mathlib.h
index eed294b..aac2d4d 100644
--- a/math/include/mathlib.h
+++ b/math/include/mathlib.h
@@ -5,6 +5,9 @@
* SPDX-License-Identifier: MIT
*/
+float sinf (float);
+float cosf (float);
+float tanf (float);
float expf (float);
float exp2f (float);
float logf (float);
diff --git a/math/log.c b/math/log.c
index b85d3ff..1283ef2 100644
--- a/math/log.c
+++ b/math/log.c
@@ -5,7 +5,6 @@
* SPDX-License-Identifier: MIT
*/
-#include <float.h>
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -156,7 +155,4 @@ log (double x)
#if USE_GLIBC_ABI
strong_alias (log, __log_finite)
hidden_alias (log, __ieee754_log)
-# if LDBL_MANT_DIG == 53
-long double logl (long double x) { return log (x); }
-# endif
#endif
diff --git a/math/log2.c b/math/log2.c
index 804fb85..478b33d 100644
--- a/math/log2.c
+++ b/math/log2.c
@@ -5,7 +5,6 @@
* SPDX-License-Identifier: MIT
*/
-#include <float.h>
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -135,7 +134,4 @@ log2 (double x)
#if USE_GLIBC_ABI
strong_alias (log2, __log2_finite)
hidden_alias (log2, __ieee754_log2)
-# if LDBL_MANT_DIG == 53
-long double log2l (long double x) { return log2 (x); }
-# endif
#endif
diff --git a/math/logf.c b/math/logf.c
index ee3120a..9c3657b 100644
--- a/math/logf.c
+++ b/math/logf.c
@@ -5,6 +5,10 @@
* SPDX-License-Identifier: MIT
*/
+#if WANT_SINGLEPREC
+#include "single/e_logf.c"
+#else
+
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -77,3 +81,4 @@ logf (float x)
strong_alias (logf, __logf_finite)
hidden_alias (logf, __ieee754_logf)
#endif
+#endif
diff --git a/math/logf_data.c b/math/logf_data.c
index 53c5f62..cee9271 100644
--- a/math/logf_data.c
+++ b/math/logf_data.c
@@ -5,6 +5,8 @@
* SPDX-License-Identifier: MIT
*/
+#if !WANT_SINGLEPREC
+
#include "math_config.h"
const struct logf_data __logf_data = {
@@ -31,3 +33,4 @@ const struct logf_data __logf_data = {
-0x1.00ea348b88334p-2, 0x1.5575b0be00b6ap-2, -0x1.ffffef20a4123p-2,
}
};
+#endif
diff --git a/math/pow.c b/math/pow.c
index 493488d..e55f159 100644
--- a/math/pow.c
+++ b/math/pow.c
@@ -5,7 +5,6 @@
* SPDX-License-Identifier: MIT
*/
-#include <float.h>
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -372,7 +371,4 @@ pow (double x, double y)
#if USE_GLIBC_ABI
strong_alias (pow, __pow_finite)
hidden_alias (pow, __ieee754_pow)
-# if LDBL_MANT_DIG == 53
-long double powl (long double x, long double y) { return pow (x, y); }
-# endif
#endif
diff --git a/math/powf.c b/math/powf.c
index 1534a09..1149842 100644
--- a/math/powf.c
+++ b/math/powf.c
@@ -5,6 +5,10 @@
* SPDX-License-Identifier: MIT
*/
+#if WANT_SINGLEPREC
+#include "single/e_powf.c"
+#else
+
#include <math.h>
#include <stdint.h>
#include "math_config.h"
@@ -219,3 +223,4 @@ powf (float x, float y)
strong_alias (powf, __powf_finite)
hidden_alias (powf, __ieee754_powf)
#endif
+#endif
diff --git a/math/powf_log2_data.c b/math/powf_log2_data.c
index b9fbdc4..285d1bd 100644
--- a/math/powf_log2_data.c
+++ b/math/powf_log2_data.c
@@ -5,6 +5,8 @@
* SPDX-License-Identifier: MIT
*/
+#if !WANT_SINGLEPREC
+
#include "math_config.h"
const struct powf_log2_data __powf_log2_data = {
@@ -32,3 +34,4 @@ const struct powf_log2_data __powf_log2_data = {
0x1.71547652ab82bp0 * POWF_SCALE,
}
};
+#endif
diff --git a/math/rem_pio2.c b/math/rem_pio2.c
new file mode 100644
index 0000000..16edd74
--- /dev/null
+++ b/math/rem_pio2.c
@@ -0,0 +1 @@
+#include "single/e_rem_pio2.c"
diff --git a/math/rredf.c b/math/rredf.c
new file mode 100644
index 0000000..fde20f0
--- /dev/null
+++ b/math/rredf.c
@@ -0,0 +1,3 @@
+#if WANT_SINGLEPREC
+#include "single/rredf.c"
+#endif
diff --git a/math/sincosf.c b/math/sincosf.c
index e6cd41e..fb6a29d 100644
--- a/math/sincosf.c
+++ b/math/sincosf.c
@@ -5,6 +5,10 @@
* SPDX-License-Identifier: MIT
*/
+#if WANT_SINGLEPREC
+#include "single/s_sincosf.c"
+#else
+
#include <stdint.h>
#include <math.h>
#include "math_config.h"
@@ -77,3 +81,5 @@ sincosf (float y, float *sinp, float *cosp)
#endif
}
}
+
+#endif
diff --git a/math/sincosf_data.c b/math/sincosf_data.c
index 5d0b58e..2512f37 100644
--- a/math/sincosf_data.c
+++ b/math/sincosf_data.c
@@ -5,6 +5,8 @@
* SPDX-License-Identifier: MIT
*/
+#if !WANT_SINGLEPREC
+
#include <stdint.h>
#include <math.h>
#include "math_config.h"
@@ -61,3 +63,5 @@ const uint32_t __inv_pio4[24] =
0x34ddc0db, 0xddc0db62, 0xc0db6295, 0xdb629599,
0x6295993c, 0x95993c43, 0x993c4390, 0x3c439041
};
+
+#endif
diff --git a/math/sinf.c b/math/sinf.c
index 770b294..f624cde 100644
--- a/math/sinf.c
+++ b/math/sinf.c
@@ -5,6 +5,10 @@
* SPDX-License-Identifier: MIT
*/
+#if WANT_SINGLEPREC
+#include "single/s_sinf.c"
+#else
+
#include <math.h>
#include "math_config.h"
#include "sincosf.h"
@@ -65,3 +69,5 @@ sinf (float y)
else
return __math_invalidf (y);
}
+
+#endif
diff --git a/math/single/dunder.c b/math/single/dunder.c
new file mode 100644
index 0000000..faec985
--- /dev/null
+++ b/math/single/dunder.c
@@ -0,0 +1,52 @@
+/*
+ * dunder.c - manually provoke FP exceptions for mathlib
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+
+#include "math_private.h"
+#include <fenv.h>
+
+__inline double __mathlib_dbl_infnan(double x)
+{
+ return x+x;
+}
+
+__inline double __mathlib_dbl_infnan2(double x, double y)
+{
+ return x+y;
+}
+
+double __mathlib_dbl_underflow(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_UNDERFLOW);
+#endif
+ return 0x1p-767 * 0x1p-767;
+}
+
+double __mathlib_dbl_overflow(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_OVERFLOW);
+#endif
+ return 0x1p+769 * 0x1p+769;
+}
+
+double __mathlib_dbl_invalid(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_INVALID);
+#endif
+ return 0.0 / 0.0;
+}
+
+double __mathlib_dbl_divzero(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_DIVBYZERO);
+#endif
+ return 1.0 / 0.0;
+}
diff --git a/math/single/e_expf.c b/math/single/e_expf.c
new file mode 100644
index 0000000..739fe1d
--- /dev/null
+++ b/math/single/e_expf.c
@@ -0,0 +1,117 @@
+/*
+ * e_expf.c - single-precision exp function
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+/*
+ * Algorithm was once taken from Cody & Waite, but has been munged
+ * out of all recognition by SGT.
+ */
+
+#include <math.h>
+#include <errno.h>
+#include "math_private.h"
+
+float
+expf(float X)
+{
+ int N; float XN, g, Rg, Result;
+ unsigned ix = fai(X), edgecaseflag = 0;
+
+ /*
+ * Handle infinities, NaNs and big numbers.
+ */
+ if (__builtin_expect((ix << 1) - 0x67000000 > 0x85500000 - 0x67000000, 0)) {
+ if (!(0x7f800000 & ~ix)) {
+ if (ix == 0xff800000)
+ return 0.0f;
+ else
+ return FLOAT_INFNAN(X);/* do the right thing with both kinds of NaN and with +inf */
+ } else if ((ix << 1) < 0x67000000) {
+ return 1.0f; /* magnitude so small the answer can't be distinguished from 1 */
+ } else if ((ix << 1) > 0x85a00000) {
+ __set_errno(ERANGE);
+ if (ix & 0x80000000) {
+ return FLOAT_UNDERFLOW;
+ } else {
+ return FLOAT_OVERFLOW;
+ }
+ } else {
+ edgecaseflag = 1;
+ }
+ }
+
+ /*
+ * Split the input into an integer multiple of log(2)/4, and a
+ * fractional part.
+ */
+ XN = X * (4.0f*1.4426950408889634074f);
+#ifdef __TARGET_FPU_SOFTVFP
+ XN = _frnd(XN);
+ N = (int)XN;
+#else
+ N = (int)(XN + (ix & 0x80000000 ? -0.5f : 0.5f));
+ XN = N;
+#endif
+ g = (X - XN * 0x1.62ep-3F) - XN * 0x1.0bfbe8p-17F; /* prec-and-a-half representation of log(2)/4 */
+
+ /*
+ * Now we compute exp(X) in, conceptually, three parts:
+ * - a pure power of two which we get from N>>2
+ * - exp(g) for g in [-log(2)/8,+log(2)/8], which we compute
+ * using a Remez-generated polynomial approximation
+ * - exp(k*log(2)/4) (aka 2^(k/4)) for k in [0..3], which we
+ * get from a lookup table in precision-and-a-half and
+ * multiply by g.
+ *
+ * We gain a bit of extra precision by the fact that actually
+ * our polynomial approximation gives us exp(g)-1, and we add
+ * the 1 back on by tweaking the prec-and-a-half multiplication
+ * step.
+ *
+ * Coefficients generated by the command
+
+./auxiliary/remez.jl --variable=g --suffix=f -- '-log(BigFloat(2))/8' '+log(BigFloat(2))/8' 3 0 '(expm1(x))/x'
+
+ */
+ Rg = g * (
+ 9.999999412829185331953781321128516523408059996430919985217971370689774264850229e-01f+g*(4.999999608551332693833317084753864837160947932961832943901913087652889900683833e-01f+g*(1.667292360203016574303631953046104769969440903672618034272397630620346717392378e-01f+g*(4.168230895653321517750133783431970715648192153539929404872173693978116154823859e-02f)))
+ );
+
+ /*
+ * Do the table lookup and combine it with Rg, to get our final
+ * answer apart from the exponent.
+ */
+ {
+ static const float twotokover4top[4] = { 0x1p+0F, 0x1.306p+0F, 0x1.6ap+0F, 0x1.ae8p+0F };
+ static const float twotokover4bot[4] = { 0x0p+0F, 0x1.fc1464p-13F, 0x1.3cccfep-13F, 0x1.3f32b6p-13F };
+ static const float twotokover4all[4] = { 0x1p+0F, 0x1.306fep+0F, 0x1.6a09e6p+0F, 0x1.ae89fap+0F };
+ int index = (N & 3);
+ Rg = twotokover4top[index] + (twotokover4bot[index] + twotokover4all[index]*Rg);
+ N >>= 2;
+ }
+
+ /*
+ * Combine the output exponent and mantissa, and return.
+ */
+ if (__builtin_expect(edgecaseflag, 0)) {
+ Result = fhex(((N/2) << 23) + 0x3f800000);
+ Result *= Rg;
+ Result *= fhex(((N-N/2) << 23) + 0x3f800000);
+ /*
+ * Step not mentioned in C&W: set errno reliably.
+ */
+ if (fai(Result) == 0)
+ return MATHERR_EXPF_UFL(Result);
+ if (fai(Result) == 0x7f800000)
+ return MATHERR_EXPF_OFL(Result);
+ return FLOAT_CHECKDENORM(Result);
+ } else {
+ Result = fhex(N * 8388608.0f + (float)0x3f800000);
+ Result *= Rg;
+ }
+
+ return Result;
+}
diff --git a/math/single/e_logf.c b/math/single/e_logf.c
new file mode 100644
index 0000000..aa29489
--- /dev/null
+++ b/math/single/e_logf.c
@@ -0,0 +1,153 @@
+/*
+ * e_logf.c - single precision log function
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+/*
+ * Algorithm was once taken from Cody & Waite, but has been munged
+ * out of all recognition by SGT.
+ */
+
+#include <math.h>
+#include <errno.h>
+#include "math_private.h"
+
+float
+logf(float X)
+{
+ int N = 0;
+ int aindex;
+ float a, x, s;
+ unsigned ix = fai(X);
+
+ if (__builtin_expect((ix - 0x00800000) >= 0x7f800000 - 0x00800000, 0)) {
+ if ((ix << 1) > 0xff000000) /* NaN */
+ return FLOAT_INFNAN(X);
+ if (ix == 0x7f800000) /* +inf */
+ return X;
+ if (X < 0) { /* anything negative */
+ return MATHERR_LOGF_NEG(X);
+ }
+ if (X == 0) {
+ return MATHERR_LOGF_0(X);
+ }
+ /* That leaves denormals. */
+ N = -23;
+ X *= 0x1p+23F;
+ ix = fai(X);
+ }
+
+ /*
+ * Separate X into three parts:
+ * - 2^N for some integer N
+ * - a number a of the form (1+k/8) for k=0,...,7
+ * - a residual which we compute as s = (x-a)/(x+a), for
+ * x=X/2^N.
+ *
+ * We pick the _nearest_ (N,a) pair, so that (x-a) has magnitude
+ * at most 1/16. Hence, we must round things that are just
+ * _below_ a power of two up to the next power of two, so this
+ * isn't as simple as extracting the raw exponent of the FP
+ * number. Instead we must grab the exponent together with the
+ * top few bits of the mantissa, and round (in integers) there.
+ */
+ {
+ int rounded = ix + 0x00080000;
+ int Nnew = (rounded >> 23) - 127;
+ aindex = (rounded >> 20) & 7;
+ a = fhex(0x3f800000 + (aindex << 20));
+ N += Nnew;
+ x = fhex(ix - (Nnew << 23));
+ }
+
+ if (!N && !aindex) {
+ /*
+ * Use an alternative strategy for very small |x|, which
+ * avoids the 1ULP of relative error introduced in the
+ * computation of s. If our nearest (N,a) pair is N=0,a=1,
+ * that means we have -1/32 < x-a < 1/16, on which interval
+ * the ordinary series for log(1+z) (setting z-x-a) will
+ * converge adequately fast; so we can simply find an
+ * approximation to log(1+z)/z good on that interval and
+ * scale it by z on the way out.
+ *
+ * Coefficients generated by the command
+
+./auxiliary/remez.jl --variable=z --suffix=f -- '-1/BigFloat(32)' '+1/BigFloat(16)' 3 0 '(log1p(x)-x)/x^2'
+
+ */
+ float z = x - 1.0f;
+ float p = z*z * (
+ -4.999999767382730053173434595877399055021398381370452534949864039404089549132551e-01f+z*(3.333416379155995401749506866323446447523793085809161350343357014272193712456391e-01f+z*(-2.501299948811686421962724839011563450757435183422532362736159418564644404218257e-01f+z*(1.903576945606738444146078468935429697455230136403008172485495359631510244557255e-01f)))
+ );
+
+ return z + p;
+ }
+
+ /*
+ * Now we have N, a and x correct, so that |x-a| <= 1/16.
+ * Compute s.
+ *
+ * (Since |x+a| >= 2, this means that |s| will be at most 1/32.)
+ */
+ s = (x - a) / (x + a);
+
+ /*
+ * The point of computing s = (x-a)/(x+a) was that this makes x
+ * equal to a * (1+s)/(1-s). So we can now compute log(x) by
+ * means of computing log((1+s)/(1-s)) (which has a more
+ * efficiently converging series), and adding log(a) which we
+ * obtain from a lookup table.
+ *
+ * So our full answer to log(X) is now formed by adding together
+ * N*log(2) + log(a) + log((1+s)/(1-s)).
+ *
+ * Now log((1+s)/(1-s)) has the exact Taylor series
+ *
+ * 2s + 2s^3/3 + 2s^5/5 + ...
+ *
+ * and what we do is to compute all but the first term of that
+ * as a polynomial approximation in s^2, then add on the first
+ * term - and all the other bits and pieces above - in
+ * precision-and-a-half so as to keep the total error down.
+ */
+ {
+ float s2 = s*s;
+
+ /*
+ * We want a polynomial L(s^2) such that
+ *
+ * 2s + s^3*L(s^2) = log((1+s)/(1-s))
+ *
+ * => L(s^2) = (log((1+s)/(1-s)) - 2s) / s^3
+ *
+ * => L(z) = (log((1+sqrt(z))/(1-sqrt(z))) - 2*sqrt(z)) / sqrt(z)^3
+ *
+ * The required range of the polynomial is only [0,1/32^2].
+ *
+ * Our accuracy requirement for the polynomial approximation
+ * is that we don't want to introduce any error more than
+ * about 2^-23 times the _top_ bit of s. But the value of
+ * the polynomial has magnitude about s^3; and since |s| <
+ * 2^-5, this gives us |s^3/s| < 2^-10. In other words,
+ * our approximation only needs to be accurate to 13 bits or
+ * so before its error is lost in the noise when we add it
+ * to everything else.
+ *
+ * Coefficients generated by the command
+
+./auxiliary/remez.jl --variable=s2 --suffix=f -- '0' '1/BigFloat(32^2)' 1 0 '(abs(x) < 1e-20 ? BigFloat(2)/3 + 2*x/5 + 2*x^2/7 + 2*x^3/9 : (log((1+sqrt(x))/(1-sqrt(x)))-2*sqrt(x))/sqrt(x^3))'
+
+ */
+ float p = s * s2 * (
+ 6.666666325680271091157649745099739739798210281016897722498744752867165138320995e-01f+s2*(4.002792299542401431889592846825025487338520940900492146195427243856292349188402e-01f)
+ );
+
+ static const float log2hi = 0x1.62ep-1F, log2lo = 0x1.0bfbe8p-15F;
+ static const float logahi[8] = { 0x0p+0F, 0x1.e26p-4F, 0x1.c8ep-3F, 0x1.46p-2F, 0x1.9f2p-2F, 0x1.f12p-2F, 0x1.1e8p-1F, 0x1.41cp-1F };
+ static const float logalo[8] = { 0x0p+0F, 0x1.076e2ap-16F, 0x1.f7c79ap-15F, 0x1.8bc21cp-14F, 0x1.23eccp-14F, 0x1.1ebf5ep-15F, 0x1.7d79c2p-15F, 0x1.8fe846p-13F };
+ return (N*log2hi + logahi[aindex]) + (2.0f*s + (N*log2lo + logalo[aindex] + p));
+ }
+}
diff --git a/math/single/e_powf.c b/math/single/e_powf.c
new file mode 100644
index 0000000..fa000f6
--- /dev/null
+++ b/math/single/e_powf.c
@@ -0,0 +1,658 @@
+/*
+ * e_powf.c - single-precision power function
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <math.h>
+#include <errno.h>
+#include "math_private.h"
+
+float
+powf(float x, float y)
+{
+ float logh, logl;
+ float rlogh, rlogl;
+ float sign = 1.0f;
+ int expadjust = 0;
+ unsigned ix, iy;
+
+ ix = fai(x);
+ iy = fai(y);
+
+ if (__builtin_expect((ix - 0x00800000) >= (0x7f800000 - 0x00800000) ||
+ ((iy << 1) + 0x02000000) < 0x40000000, 0)) {
+ /*
+ * The above test rules out, as quickly as I can see how to,
+ * all possible inputs except for a normalised positive x
+ * being raised to the power of a normalised (and not
+ * excessively small) y. That's the fast-path case: if
+ * that's what the user wants, we can skip all of the
+ * difficult special-case handling.
+ *
+ * Now we must identify, as efficiently as we can, cases
+ * which will return to the fast path with a little tidying
+ * up. These are, in order of likelihood and hence of
+ * processing:
+ *
+ * - a normalised _negative_ x raised to the power of a
+ * non-zero finite y. Having identified this case, we
+ * must categorise y into one of the three categories
+ * 'odd integer', 'even integer' and 'non-integer'; for
+ * the last of these we return an error, while for the
+ * other two we rejoin the main code path having rendered
+ * x positive and stored an appropriate sign to append to
+ * the eventual result.
+ *
+ * - a _denormal_ x raised to the power of a non-zero
+ * finite y, in which case we multiply it up by a power
+ * of two to renormalise it, store an appropriate
+ * adjustment for its base-2 logarithm, and depending on
+ * the sign of y either return straight to the main code
+ * path or go via the categorisation of y above.
+ *
+ * - any of the above kinds of x raised to the power of a
+ * zero, denormal, nearly-denormal or nearly-infinite y,
+ * in which case we must do the checks on x as above but
+ * otherwise the algorithm goes through basically
+ * unchanged. Denormal and very tiny y values get scaled
+ * up to something not in range of accidental underflow
+ * when split into prec-and-a-half format; very large y
+ * values get scaled down by a factor of two to prevent
+ * CLEARBOTTOMHALF's round-up from overflowing them to
+ * infinity. (Of course the _output_ will overflow either
+ * way - the largest y value that can possibly yield a
+ * finite result is well below this range anyway - so
+ * this is a safe change.)
+ */
+ if (__builtin_expect(((iy << 1) + 0x02000000) >= 0x40000000, 1)) { /* normalised and sensible y */
+ y_ok_check_x:
+
+ if (__builtin_expect((ix - 0x80800000) < (0xff800000 - 0x80800000), 1)) { /* normal but negative x */
+ y_ok_x_negative:
+
+ x = fabsf(x);
+ ix = fai(x);
+
+ /*
+ * Determine the parity of y, if it's an integer at
+ * all.
+ */
+ {
+ int yexp, yunitsbit;
+
+ /*
+ * Find the exponent of y.
+ */
+ yexp = (iy >> 23) & 0xFF;
+ /*
+ * Numbers with an exponent smaller than 0x7F
+ * are strictly smaller than 1, and hence must
+ * be fractional.
+ */
+ if (yexp < 0x7F)
+ return MATHERR_POWF_NEGFRAC(x,y);
+ /*
+ * Numbers with an exponent at least 0x97 are by
+ * definition even integers.
+ */
+ if (yexp >= 0x97)
+ goto mainpath; /* rejoin main code, giving positive result */
+ /*
+ * In between, we must check the mantissa.
+ *
+ * Note that this case includes yexp==0x7f,
+ * which means 1 point something. In this case,
+ * the 'units bit' we're testing is semantically
+ * the lowest bit of the exponent field, not the
+ * leading 1 on the mantissa - but fortunately,
+ * that bit position will just happen to contain
+ * the 1 that we would wish it to, because the
+ * exponent describing that particular case just
+ * happens to be odd.
+ */
+ yunitsbit = 0x96 - yexp;
+ if (iy & ((1 << yunitsbit)-1))
+ return MATHERR_POWF_NEGFRAC(x,y);
+ else if (iy & (1 << yunitsbit))
+ sign = -1.0f; /* y is odd; result should be negative */
+ goto mainpath; /* now we can rejoin the main code */
+ }
+ } else if (__builtin_expect((ix << 1) != 0 && (ix << 1) < 0x01000000, 0)) { /* denormal x */
+ /*
+ * Renormalise x.
+ */
+ x *= 0x1p+27F;
+ ix = fai(x);
+ /*
+ * Set expadjust to compensate for that.
+ */
+ expadjust = -27;
+
+ /* Now we need to handle negative x as above. */
+ if (ix & 0x80000000)
+ goto y_ok_x_negative;
+ else
+ goto mainpath;
+ } else if ((ix - 0x00800000) < (0x7f800000 - 0x00800000)) {
+ /* normal positive x, back here from denormal-y case below */
+ goto mainpath;
+ }
+ } else if (((iy << 1) + 0x02000000) >= 0x02000000) { /* denormal, nearly-denormal or zero y */
+ if (y == 0.0F) {
+ /*
+ * y == 0. Any finite x returns 1 here. (Quiet NaNs
+ * do too, but we handle that below since we don't
+ * mind doing them more slowly.)
+ */
+ if ((ix << 1) != 0 && (ix << 1) < 0xFF000000)
+ return 1.0f;
+ } else {
+ /*
+ * Denormal or very very small y. In this situation
+ * we have to be a bit careful, because when we
+ * break up y into precision-and-a-half later on we
+ * risk working with denormals and triggering
+ * underflow exceptions within this function that
+ * aren't related to the smallness of the output. So
+ * here we convert all such y values into a standard
+ * small-but-not-too-small value which will give the
+ * same output.
+ *
+ * What value should that be? Well, we work in
+ * 16*log2(x) below (equivalently, log to the base
+ * 2^{1/16}). So the maximum magnitude of that for
+ * any finite x is about 2416 (= 16 * (128+23), for
+ * log of the smallest denormal x), i.e. certainly
+ * less than 2^12. If multiplying that by y gives
+ * anything of magnitude less than 2^-32 (and even
+ * that's being generous), the final output will be
+ * indistinguishable from 1. So any value of y with
+ * magnitude less than 2^-(32+12) = 2^-44 is
+ * completely indistinguishable from any other such
+ * value. Hence we got here in the first place by
+ * checking the exponent of y against 64 (i.e. -63,
+ * counting the exponent bias), so we might as well
+ * normalise all tiny y values to the same threshold
+ * of 2^-64.
+ */
+ iy = 0x1f800000 | (iy & 0x80000000); /* keep the sign; that's important */
+ y = fhex(iy);
+ }
+ goto y_ok_check_x;
+ } else if (((iy << 1) + 0x02000000) < 0x01000000) { /* y in top finite exponent bracket */
+ y = fhex(fai(y) - 0x00800000); /* scale down by a factor of 2 */
+ goto y_ok_check_x;
+ }
+
+ /*
+ * Having dealt with the above cases, we now know that
+ * either x is zero, infinite or NaN, or y is infinite or
+ * NaN, or both. We can deal with all of those cases without
+ * ever rejoining the main code path.
+ */
+ if ((unsigned)(((ix & 0x7FFFFFFF) - 0x7f800001) < 0x7fc00000 - 0x7f800001) ||
+ (unsigned)(((iy & 0x7FFFFFFF) - 0x7f800001) < 0x7fc00000 - 0x7f800001)) {
+ /*
+ * At least one signalling NaN. Do a token arithmetic
+ * operation on the two operands to provoke an exception
+ * and return the appropriate QNaN.
+ */
+ return FLOAT_INFNAN2(x,y);
+ } else if (ix==0x3f800000 || (iy << 1)==0) {
+ /*
+ * C99 says that 1^anything and anything^0 should both
+ * return 1, _even for a NaN_. I modify that slightly to
+ * apply only to QNaNs (which doesn't violate C99, since
+ * C99 doesn't specify anything about SNaNs at all),
+ * because I can't bring myself not to throw an
+ * exception on an SNaN since its _entire purpose_ is to
+ * throw an exception whenever touched.
+ */
+ return 1.0f;
+ } else
+ if (((ix & 0x7FFFFFFF) > 0x7f800000) ||
+ ((iy & 0x7FFFFFFF) > 0x7f800000)) {
+ /*
+ * At least one QNaN. Do a token arithmetic operation on
+ * the two operands to get the right one to propagate to
+ * the output.
+ */
+ return FLOAT_INFNAN2(x,y);
+ } else if (ix == 0x7f800000) {
+ /*
+ * x = +infinity. Return +infinity for positive y, +0
+ * for negative y, and 1 for zero y.
+ */
+ if (!(iy << 1))
+ return MATHERR_POWF_INF0(x,y);
+ else if (iy & 0x80000000)
+ return 0.0f;
+ else
+ return INFINITY;
+ } else {
+ /*
+ * Repeat the parity analysis of y above, returning 1
+ * (odd), 2 (even) or 0 (fraction).
+ */
+ int ypar, yexp, yunitsbit;
+ yexp = (iy >> 23) & 0xFF;
+ if (yexp < 0x7F)
+ ypar = 0;
+ else if (yexp >= 0x97)
+ ypar = 2;
+ else {
+ yunitsbit = 0x96 - yexp;
+ if (iy & ((1 << yunitsbit)-1))
+ ypar = 0;
+ else if (iy & (1 << yunitsbit))
+ ypar = 1;
+ else
+ ypar = 2;
+ }
+
+ if (ix == 0xff800000) {
+ /*
+ * x = -infinity. We return infinity or zero
+ * depending on whether y is positive or negative,
+ * and the sign is negative iff y is an odd integer.
+ * (SGT: I don't like this, but it's what C99
+ * mandates.)
+ */
+ if (!(iy & 0x80000000)) {
+ if (ypar == 1)
+ return -INFINITY;
+ else
+ return INFINITY;
+ } else {
+ if (ypar == 1)
+ return -0.0f;
+ else
+ return +0.0f;
+ }
+ } else if (ix == 0) {
+ /*
+ * x = +0. We return +0 for all positive y including
+ * infinity; a divide-by-zero-like error for all
+ * negative y including infinity; and an 0^0 error
+ * for zero y.
+ */
+ if ((iy << 1) == 0)
+ return MATHERR_POWF_00(x,y);
+ else if (iy & 0x80000000)
+ return MATHERR_POWF_0NEGEVEN(x,y);
+ else
+ return +0.0f;
+ } else if (ix == 0x80000000) {
+ /*
+ * x = -0. We return errors in almost all cases (the
+ * exception being positive integer y, in which case
+ * we return a zero of the appropriate sign), but
+ * the errors are almost all different. Gah.
+ */
+ if ((iy << 1) == 0)
+ return MATHERR_POWF_00(x,y);
+ else if (iy == 0x7f800000)
+ return MATHERR_POWF_NEG0FRAC(x,y);
+ else if (iy == 0xff800000)
+ return MATHERR_POWF_0NEG(x,y);
+ else if (iy & 0x80000000)
+ return (ypar == 0 ? MATHERR_POWF_0NEG(x,y) :
+ ypar == 1 ? MATHERR_POWF_0NEGODD(x,y) :
+ /* ypar == 2 ? */ MATHERR_POWF_0NEGEVEN(x,y));
+ else
+ return (ypar == 0 ? MATHERR_POWF_NEG0FRAC(x,y) :
+ ypar == 1 ? -0.0f :
+ /* ypar == 2 ? */ +0.0f);
+ } else {
+ /*
+ * Now we know y is an infinity of one sign or the
+ * other and x is finite and nonzero. If x == -1 (+1
+ * is already ruled out), we return +1; otherwise
+ * C99 mandates that we return either +0 or +inf,
+ * the former iff exactly one of |x| < 1 and y<0 is
+ * true.
+ */
+ if (ix == 0xbf800000) {
+ return +1.0f;
+ } else if (!((ix << 1) < 0x7f000000) ^ !(iy & 0x80000000)) {
+ return +0.0f;
+ }
+ else {
+ return INFINITY;
+ }
+ }
+ }
+ }
+
+ mainpath:
+
+#define PHMULTIPLY(rh,rl, xh,xl, yh,yl) do { \
+ float tmph, tmpl; \
+ tmph = (xh) * (yh); \
+ tmpl = (xh) * (yl) + (xl) * ((yh)+(yl)); \
+/* printf("PHMULTIPLY: tmp=%08x+%08x\n", fai(tmph), fai(tmpl)); */ \
+ (rh) = CLEARBOTTOMHALF(tmph + tmpl); \
+ (rl) = tmpl + (tmph - (rh)); \
+} while (0)
+
+/*
+ * Same as the PHMULTIPLY macro above, but bounds the absolute value
+ * of rh+rl. In multiplications uncontrolled enough that rh can go
+ * infinite, we can get an IVO exception from the subtraction tmph -
+ * rh, so we should spot that case in advance and avoid it.
+ */
+#define PHMULTIPLY_SATURATE(rh,rl, xh,xl, yh,yl, bound) do { \
+ float tmph, tmpl; \
+ tmph = (xh) * (yh); \
+ if (fabsf(tmph) > (bound)) { \
+ (rh) = copysignf((bound),(tmph)); \
+ (rl) = 0.0f; \
+ } else { \
+ tmpl = (xh) * (yl) + (xl) * ((yh)+(yl)); \
+ (rh) = CLEARBOTTOMHALF(tmph + tmpl); \
+ (rl) = tmpl + (tmph - (rh)); \
+ } \
+ } while (0)
+
+ /*
+ * Determine log2 of x to relative prec-and-a-half, as logh +
+ * logl.
+ *
+ * Well, we're actually computing 16*log2(x), so that it's the
+ * right size for the subsequently fiddly messing with powers of
+ * 2^(1/16) in the exp step at the end.
+ */
+ if (__builtin_expect((ix - 0x3f7ff000) <= (0x3f801000 - 0x3f7ff000), 0)) {
+ /*
+ * For x this close to 1, we write x = 1 + t and then
+ * compute t - t^2/2 + t^3/3 - t^4/4; and the neat bit is
+ * that t itself, being the bottom half of an input
+ * mantissa, is in half-precision already, so the output is
+ * naturally in canonical prec-and-a-half form.
+ */
+ float t = x - 1.0;
+ float lnh, lnl;
+ /*
+ * Compute natural log of x in prec-and-a-half.
+ */
+ lnh = t;
+ lnl = - (t * t) * ((1.0f/2.0f) - t * ((1.0f/3.0f) - t * (1.0f/4.0f)));
+
+ /*
+ * Now we must scale by 16/log(2), still in prec-and-a-half,
+ * to turn this from natural log(x) into 16*log2(x).
+ */
+ PHMULTIPLY(logh, logl, lnh, lnl, 0x1.716p+4F, -0x1.7135a8p-9F);
+ } else {
+ /*
+ * For all other x, we start by normalising to [1,2), and
+ * then dividing that further into subintervals. For each
+ * subinterval we pick a number a in that interval, compute
+ * s = (x-a)/(x+a) in precision-and-a-half, and then find
+ * the log base 2 of (1+s)/(1-s), still in precision-and-a-
+ * half.
+ *
+ * Why would we do anything so silly? For two main reasons.
+ *
+ * Firstly, if s = (x-a)/(x+a), then a bit of algebra tells
+ * us that x = a * (1+s)/(1-s); so once we've got
+ * log2((1+s)/(1-s)), we need only add on log2(a) and then
+ * we've got log2(x). So this lets us treat all our
+ * subintervals in essentially the same way, rather than
+ * requiring a separate approximation for each one; the only
+ * correction factor we need is to store a table of the
+ * base-2 logs of all our values of a.
+ *
+ * Secondly, log2((1+s)/(1-s)) is a nice thing to compute,
+ * once we've got s. Switching to natural logarithms for the
+ * moment (it's only a scaling factor to sort that out at
+ * the end), we write it as the difference of two logs:
+ *
+ * log((1+s)/(1-s)) = log(1+s) - log(1-s)
+ *
+ * Now recall that Taylor series expansion gives us
+ *
+ * log(1+s) = s - s^2/2 + s^3/3 - ...
+ *
+ * and therefore we also have
+ *
+ * log(1-s) = -s - s^2/2 - s^3/3 - ...
+ *
+ * These series are exactly the same except that the odd
+ * terms (s, s^3 etc) have flipped signs; so subtracting the
+ * latter from the former gives us
+ *
+ * log(1+s) - log(1-s) = 2s + 2s^3/3 + 2s^5/5 + ...
+ *
+ * which requires only half as many terms to be computed
+ * before the powers of s get too small to see. Then, of
+ * course, we have to scale the result by 1/log(2) to
+ * convert natural logs into logs base 2.
+ *
+ * To compute the above series in precision-and-a-half, we
+ * first extract a factor of 2s (which we can multiply back
+ * in later) so that we're computing 1 + s^2/3 + s^4/5 + ...
+ * and then observe that if s starts off small enough to
+ * make s^2/3 at most 2^-12, we need only compute the first
+ * couple of terms in laborious prec-and-a-half, and can
+ * delegate everything after that to a simple polynomial
+ * approximation whose error will end up at the bottom of
+ * the low word of the result.
+ *
+ * How many subintervals does that mean we need?
+ *
+ * To go back to s = (x-a)/(x+a). Let x = a + e, for some
+ * positive e. Then |s| = |e| / |2a+e| <= |e/2a|. So suppose
+ * we have n subintervals of equal width covering the space
+ * from 1 to 2. If a is at the centre of each interval, then
+ * we have e at most 1/2n and a can equal any of 1, 1+1/n,
+ * 1+2/n, ... 1+(n-1)/n. In that case, clearly the largest
+ * value of |e/2a| is given by the largest e (i.e. 1/2n) and
+ * the smallest a (i.e. 1); so |s| <= 1/4n. Hence, when we
+ * know how big we're prepared to let s be, we simply make
+ * sure 1/4n is at most that.
+ *
+ * And if we want s^2/3 to be at most 2^-12, then that means
+ * s^2 is at most 3*2^-12, so that s is at most sqrt(3)*2^-6
+ * = 0.02706. To get 1/4n smaller than that, we need to have
+ * n>=9.23; so we'll set n=16 (for ease of bit-twiddling),
+ * and then s is at most 1/64.
+ */
+ int n, i;
+ float a, ax, sh, sl, lsh, lsl;
+
+ /*
+ * Let ax be x normalised to a single exponent range.
+ * However, the exponent range in question is not a simple
+ * one like [1,2). What we do is to round up the top four
+ * bits of the mantissa, so that the top 1/32 of each
+ * natural exponent range rounds up to the next one and is
+ * treated as a displacement from the lowest a in that
+ * range.
+ *
+ * So this piece of bit-twiddling gets us our input exponent
+ * and our subinterval index.
+ */
+ n = (ix + 0x00040000) >> 19;
+ i = n & 15;
+ n = ((n >> 4) & 0xFF) - 0x7F;
+ ax = fhex(ix - (n << 23));
+ n += expadjust;
+
+ /*
+ * Compute the subinterval centre a.
+ */
+ a = 1.0f + i * (1.0f/16.0f);
+
+ /*
+ * Compute s = (ax-a)/(ax+a), in precision-and-a-half.
+ */
+ {
+ float u, vh, vl, vapprox, rvapprox;
+
+ u = ax - a; /* exact numerator */
+ vapprox = ax + a; /* approximate denominator */
+ vh = CLEARBOTTOMHALF(vapprox);
+ vl = (a - vh) + ax; /* vh+vl is exact denominator */
+ rvapprox = 1.0f/vapprox; /* approximate reciprocal of denominator */
+
+ sh = CLEARBOTTOMHALF(u * rvapprox);
+ sl = ((u - sh*vh) - sh*vl) * rvapprox;
+ }
+
+ /*
+ * Now compute log2(1+s) - log2(1-s). We do this in several
+ * steps.
+ *
+ * By polynomial approximation, we compute
+ *
+ * log(1+s) - log(1-s)
+ * p = ------------------- - 1
+ * 2s
+ *
+ * in single precision only, using a single-precision
+ * approximation to s. This polynomial has s^2 as its
+ * lowest-order term, so we expect the result to be in
+ * [0,2^-12).
+ *
+ * Then we form a prec-and-a-half number out of 1 and p,
+ * which is therefore equal to (log(1+s) - log(1-s))/(2s).
+ *
+ * Finally, we do two prec-and-a-half multiplications: one
+ * by s itself, and one by the constant 32/log(2).
+ */
+ {
+ float s = sh + sl;
+ float s2 = s*s;
+ /*
+ * p is actually a polynomial in s^2, with the first
+ * term constrained to zero. In other words, treated on
+ * its own terms, we're computing p(s^2) such that p(x)
+ * is an approximation to the sum of the series 1/3 +
+ * x/5 + x^2/7 + ..., valid on the range [0, 1/40^2].
+ */
+ float p = s2 * (0.33333332920177422f + s2 * 0.20008275183621479f);
+ float th, tl;
+
+ PHMULTIPLY(th,tl, 1.0f,p, sh,sl);
+ PHMULTIPLY(lsh,lsl, th,tl, 0x1.716p+5F,-0x1.7135a8p-8F);
+ }
+
+ /*
+ * And our final answer for 16*log2(x) is equal to 16n (from
+ * the exponent), plus lsh+lsl (the result of the above
+ * computation), plus 16*log2(a) which we must look up in a
+ * table.
+ */
+ {
+ struct f2 { float h, l; };
+ static const struct f2 table[16] = {
+ /*
+ * When constructing this table, we have to be sure
+ * that we produce the same values of a which will
+ * be produced by the computation above. Ideally, I
+ * would tell Perl to actually do its _arithmetic_
+ * in single precision here; but I don't know a way
+ * to do that, so instead I just scrupulously
+ * convert every intermediate value to and from SP.
+ */
+ // perl -e 'for ($i=0; $i<16; $i++) { $v = unpack "f", pack "f", 1/16.0; $a = unpack "f", pack "f", $i * $v; $a = unpack "f", pack "f", $a+1.0; $l = 16*log($a)/log(2); $top = unpack "f", pack "f", int($l*256.0+0.5)/256.0; $bot = unpack "f", pack "f", $l - $top; printf "{0f_%08X,0f_%08X}, ", unpack "VV", pack "ff", $top, $bot; } print "\n"' | fold -s -w56 | sed 's/^/ /'
+ {0x0p+0F,0x0p+0F}, {0x1.66p+0F,0x1.fb7d64p-11F},
+ {0x1.5cp+1F,0x1.a39fbep-15F}, {0x1.fcp+1F,-0x1.f4a37ep-10F},
+ {0x1.49cp+2F,-0x1.87b432p-10F}, {0x1.91cp+2F,-0x1.15db84p-12F},
+ {0x1.d68p+2F,-0x1.583f9ap-11F}, {0x1.0c2p+3F,-0x1.f5fe54p-10F},
+ {0x1.2b8p+3F,0x1.a39fbep-16F}, {0x1.49ap+3F,0x1.e12f34p-11F},
+ {0x1.66ap+3F,0x1.1c8f12p-18F}, {0x1.828p+3F,0x1.3ab7cep-14F},
+ {0x1.9d6p+3F,-0x1.30158p-12F}, {0x1.b74p+3F,0x1.291eaap-10F},
+ {0x1.d06p+3F,-0x1.8125b4p-10F}, {0x1.e88p+3F,0x1.8d66c4p-10F},
+ };
+ float lah = table[i].h, lal = table[i].l;
+ float fn = 16*n;
+ logh = CLEARBOTTOMHALF(lsl + lal + lsh + lah + fn);
+ logl = lsl - ((((logh - fn) - lah) - lsh) - lal);
+ }
+ }
+
+ /*
+ * Now we have 16*log2(x), multiply it by y in prec-and-a-half.
+ */
+ {
+ float yh, yl;
+ int savedexcepts;
+
+ yh = CLEARBOTTOMHALF(y);
+ yl = y - yh;
+
+ /* This multiplication could become infinite, so to avoid IVO
+ * in PHMULTIPLY we bound the output at 4096, which is big
+ * enough to allow any non-overflowing case through
+ * unmodified. Also, we must mask out the OVF exception, which
+ * we won't want left in the FP status word in the case where
+ * rlogh becomes huge and _negative_ (since that will be an
+ * underflow from the perspective of powf's return value, not
+ * an overflow). */
+ savedexcepts = __ieee_status(0,0) & (FE_IEEE_OVERFLOW | FE_IEEE_UNDERFLOW);
+ PHMULTIPLY_SATURATE(rlogh, rlogl, logh, logl, yh, yl, 4096.0f);
+ __ieee_status(FE_IEEE_OVERFLOW | FE_IEEE_UNDERFLOW, savedexcepts);
+ }
+
+ /*
+ * And raise 2 to the power of whatever that gave. Again, this
+ * is done in three parts: the fractional part of our input is
+ * fed through a polynomial approximation, all but the bottom
+ * four bits of the integer part go straight into the exponent,
+ * and the bottom four bits of the integer part index into a
+ * lookup table of powers of 2^(1/16) in prec-and-a-half.
+ */
+ {
+ float rlog = rlogh + rlogl;
+ int i16 = (rlog + (rlog < 0 ? -0.5f : +0.5f));
+ float rlogi = i16 >> 4;
+
+ float x = rlogl + (rlogh - i16);
+
+ static const float powersof2to1over16top[16] = { 0x1p+0F, 0x1.0b4p+0F, 0x1.172p+0F, 0x1.238p+0F, 0x1.306p+0F, 0x1.3dep+0F, 0x1.4bep+0F, 0x1.5aap+0F, 0x1.6ap+0F, 0x1.7ap+0F, 0x1.8acp+0F, 0x1.9c4p+0F, 0x1.ae8p+0F, 0x1.c18p+0F, 0x1.d58p+0F, 0x1.ea4p+0F };
+ static const float powersof2to1over16bot[16] = { 0x0p+0F, 0x1.586cfap-12F, 0x1.7078fap-13F, 0x1.e9b9d6p-14F, 0x1.fc1464p-13F, 0x1.4c9824p-13F, 0x1.dad536p-12F, 0x1.07dd48p-12F, 0x1.3cccfep-13F, 0x1.1473ecp-12F, 0x1.ca8456p-13F, 0x1.230548p-13F, 0x1.3f32b6p-13F, 0x1.9bdd86p-12F, 0x1.8dcfbap-16F, 0x1.5f454ap-13F };
+ static const float powersof2to1over16all[16] = { 0x1p+0F, 0x1.0b5586p+0F, 0x1.172b84p+0F, 0x1.2387a6p+0F, 0x1.306fep+0F, 0x1.3dea64p+0F, 0x1.4bfdaep+0F, 0x1.5ab07ep+0F, 0x1.6a09e6p+0F, 0x1.7a1148p+0F, 0x1.8ace54p+0F, 0x1.9c4918p+0F, 0x1.ae89fap+0F, 0x1.c199bep+0F, 0x1.d5818ep+0F, 0x1.ea4afap+0F };
+ /*
+ * Coefficients generated using the command
+
+./auxiliary/remez.jl --suffix=f -- '-1/BigFloat(2)' '+1/BigFloat(2)' 2 0 'expm1(x*log(BigFloat(2))/16)/x'
+
+ */
+ float p = x * (
+ 4.332169876512769231967668743345473181486157887703125512683507537369503902991722e-02f+x*(9.384123108485637159805511308039285411735300871134684682779057580789341719567367e-04f+x*(1.355120515540562256928614563584948866224035897564701496826514330445829352922309e-05f))
+ );
+ int index = (i16 & 15);
+ p = powersof2to1over16top[index] + (powersof2to1over16bot[index] + powersof2to1over16all[index]*p);
+
+ if (
+ fabsf(rlogi) < 126.0f
+ ) {
+ return sign * p * fhex((unsigned)((127.0f+rlogi) * 8388608.0f));
+ } else if (
+ fabsf(rlogi) < 192.0f
+ ) {
+ int i = rlogi;
+ float ret;
+
+ ret = sign * p *
+ fhex((unsigned)((0x7f+i/2) * 8388608)) *
+ fhex((unsigned)((0x7f+i-i/2) * 8388608));
+
+ if ((fai(ret) << 1) == 0xFF000000)
+ return MATHERR_POWF_OFL(x, y, sign);
+ else if ((fai(ret) << 1) == 0)
+ return MATHERR_POWF_UFL(x, y, sign);
+ else
+ return FLOAT_CHECKDENORM(ret);
+ } else {
+ if (rlogi < 0)
+ return MATHERR_POWF_UFL(x, y, sign);
+ else
+ return MATHERR_POWF_OFL(x, y, sign);
+ }
+ }
+}
diff --git a/math/single/e_rem_pio2.c b/math/single/e_rem_pio2.c
new file mode 100644
index 0000000..f0e384d
--- /dev/null
+++ b/math/single/e_rem_pio2.c
@@ -0,0 +1,268 @@
+/*
+ * e_rem_pio2.c
+ *
+ * Copyright (c) 1999-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <math.h>
+#include "math_private.h"
+
+int __ieee754_rem_pio2(double x, double *y) {
+ int q;
+
+ y[1] = 0.0; /* default */
+
+ /*
+ * Simple cases: all nicked from the fdlibm version for speed.
+ */
+ {
+ static const double invpio2 = 0x1.45f306dc9c883p-1;
+ static const double pio2s[] = {
+ 0x1.921fb544p+0, /* 1.57079632673412561417e+00 */
+ 0x1.0b4611a626331p-34, /* 6.07710050650619224932e-11 */
+ 0x1.0b4611a6p-34, /* 6.07710050630396597660e-11 */
+ 0x1.3198a2e037073p-69, /* 2.02226624879595063154e-21 */
+ 0x1.3198a2ep-69, /* 2.02226624871116645580e-21 */
+ 0x1.b839a252049c1p-104, /* 8.47842766036889956997e-32 */
+ };
+
+ double z,w,t,r,fn;
+ int i,j,idx,n,ix,hx;
+
+ hx = __HI(x); /* high word of x */
+ ix = hx&0x7fffffff;
+ if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
+ {y[0] = x; y[1] = 0; return 0;}
+ if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
+ if(hx>0) {
+ z = x - pio2s[0];
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z - pio2s[1];
+#ifdef bottomhalf
+ y[1] = (z-y[0])-pio2s[1];
+#endif
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z -= pio2s[2];
+ y[0] = z - pio2s[3];
+#ifdef bottomhalf
+ y[1] = (z-y[0])-pio2s[3];
+#endif
+ }
+ return 1;
+ } else { /* negative x */
+ z = x + pio2s[0];
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z + pio2s[1];
+#ifdef bottomhalf
+ y[1] = (z-y[0])+pio2s[1];
+#endif
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z += pio2s[2];
+ y[0] = z + pio2s[3];
+#ifdef bottomhalf
+ y[1] = (z-y[0])+pio2s[3];
+#endif
+ }
+ return -1;
+ }
+ }
+ if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
+ t = fabs(x);
+ n = (int) (t*invpio2+0.5);
+ fn = (double)n;
+ r = t-fn*pio2s[0];
+ w = fn*pio2s[1]; /* 1st round good to 85 bit */
+ j = ix>>20;
+ idx = 1;
+ while (1) {
+ y[0] = r-w;
+ if (idx == 3)
+ break;
+ i = j-(((__HI(y[0]))>>20)&0x7ff);
+ if(i <= 33*idx-17)
+ break;
+ t = r;
+ w = fn*pio2s[2*idx];
+ r = t-w;
+ w = fn*pio2s[2*idx+1]-((t-r)-w);
+ idx++;
+ }
+#ifdef bottomhalf
+ y[1] = (r-y[0])-w;
+#endif
+ if(hx<0) {
+ y[0] = -y[0];
+#ifdef bottomhalf
+ y[1] = -y[1];
+#endif
+ return -n;
+ } else {
+ return n;
+ }
+ }
+ }
+
+ {
+ static const unsigned twooverpi[] = {
+ /* We start with two zero words, because they take up less
+ * space than the array bounds checking and special-case
+ * handling that would have to occur in their absence. */
+ 0, 0,
+ /* 2/pi in hex is 0.a2f9836e... */
+ 0xa2f9836e, 0x4e441529, 0xfc2757d1, 0xf534ddc0, 0xdb629599,
+ 0x3c439041, 0xfe5163ab, 0xdebbc561, 0xb7246e3a, 0x424dd2e0,
+ 0x06492eea, 0x09d1921c, 0xfe1deb1c, 0xb129a73e, 0xe88235f5,
+ 0x2ebb4484, 0xe99c7026, 0xb45f7e41, 0x3991d639, 0x835339f4,
+ 0x9c845f8b, 0xbdf9283b, 0x1ff897ff, 0xde05980f, 0xef2f118b,
+ 0x5a0a6d1f, 0x6d367ecf, 0x27cb09b7, 0x4f463f66, 0x9e5fea2d,
+ 0x7527bac7, 0xebe5f17b, 0x3d0739f7, 0x8a5292ea, 0x6bfb5fb1,
+ 0x1f8d5d08,
+ };
+
+ /*
+ * Multiprecision multiplication of this nature is more
+ * readily done in integers than in VFP, since we can use
+ * UMULL (on CPUs that support it) to multiply 32 by 32 bits
+ * at a time whereas the VFP would only be able to do 12x12
+ * without losing accuracy.
+ *
+ * So extract the mantissa of the input number as two 32-bit
+ * integers.
+ */
+ unsigned mant1 = 0x00100000 | (__HI(x) & 0xFFFFF);
+ unsigned mant2 = __LO(x);
+ /*
+ * Now work out which part of our stored value of 2/pi we're
+ * supposed to be multiplying by.
+ *
+ * Let the IEEE exponent field of x be e. With its bias
+ * removed, (e-1023) is the index of the set bit in bit 20
+ * of 'mant1' (i.e. that set bit has real place value
+ * 2^(e-1023)). So the lowest set bit in 'mant1', 52 bits
+ * further down, must have place value 2^(e-1075).
+ *
+ * We begin taking an interest in the value of 2/pi at the
+ * bit which multiplies by _that_ to give something with
+ * place value at most 2. In other words, the highest bit of
+ * 2/pi we're interested in is the one with place value
+ * 2/(2^(e-1075)) = 2^(1076-e).
+ *
+ * The bit at the top of the first zero word of the above
+ * array has place value 2^63. Hence, the bit we want to put
+ * at the top of the first word we extract from that array
+ * is the one at bit index n, where 63-n = 1076-e and hence
+ * n=e-1013.
+ */
+ int topbitindex = ((__HI(x) >> 20) & 0x7FF) - 1013;
+ int wordindex = topbitindex >> 5;
+ int shiftup = topbitindex & 31;
+ int shiftdown = 32 - shiftup;
+ unsigned scaled[8];
+ int i;
+
+ scaled[7] = scaled[6] = 0;
+
+ for (i = 6; i-- > 0 ;) {
+ /*
+ * Extract a word from our representation of 2/pi.
+ */
+ unsigned word;
+ if (shiftup)
+ word = (twooverpi[wordindex + i] << shiftup) | (twooverpi[wordindex + i + 1] >> shiftdown);
+ else
+ word = twooverpi[wordindex + i];
+ /*
+ * Multiply it by both words of our mantissa. (Should
+ * generate UMULLs where available.)
+ */
+ unsigned long long mult1 = (unsigned long long)word * mant1;
+ unsigned long long mult2 = (unsigned long long)word * mant2;
+ /*
+ * Split those up into 32-bit chunks.
+ */
+ unsigned bottom1 = (unsigned)mult1, top1 = (unsigned)(mult1 >> 32);
+ unsigned bottom2 = (unsigned)mult2, top2 = (unsigned)(mult2 >> 32);
+ /*
+ * Add those two chunks together.
+ */
+ unsigned out1, out2, out3;
+
+ out3 = bottom2;
+ out2 = top2 + bottom1;
+ out1 = top1 + (out2 < top2);
+ /*
+ * And finally add them to our 'scaled' array.
+ */
+ unsigned s3 = scaled[i+2], s2 = scaled[i+1], s1;
+ unsigned carry;
+ s3 = out3 + s3; carry = (s3 < out3);
+ s2 = out2 + s2 + carry; carry = carry ? (s2 <= out2) : (s2 < out2);
+ s1 = out1 + carry;
+
+ scaled[i+2] = s3;
+ scaled[i+1] = s2;
+ scaled[i] = s1;
+ }
+
+
+ /*
+ * The topmost set bit in mant1 is bit 20, and that has
+ * place value 2^(e-1023). The topmost bit (bit 31) of the
+ * most significant word we extracted from our twooverpi
+ * array had place value 2^(1076-e). So the product of those
+ * two bits must have place value 2^53; and that bit will
+ * have ended up as bit 19 of scaled[0]. Hence, the integer
+ * quadrant value we want to output, consisting of the bits
+ * with place values 2^1 and 2^0, must be 52 and 53 bits
+ * below that, i.e. precisely the topmost two bits of
+ * scaled[2].
+ *
+ * Or, at least, it will be once we add 1/2, to round to the
+ * _nearest_ multiple of pi/2 rather than the next one down.
+ */
+ q = (scaled[2] + (1<<29)) >> 30;
+
+ /*
+ * Now we construct the output fraction, which is most
+ * simply done in the VFP. We just extract four consecutive
+ * bit strings from our chunk of binary data, convert them
+ * to doubles, equip each with an appropriate FP exponent,
+ * add them together, and (don't forget) multiply back up by
+ * pi/2. That way we don't have to work out ourselves where
+ * the highest fraction bit ended up.
+ *
+ * Since our displacement from the nearest multiple of pi/2
+ * can be positive or negative, the topmost of these four
+ * values must be arranged with its 2^-1 bit at the very top
+ * of the word, and then treated as a _signed_ integer.
+ */
+ int i1 = (scaled[2] << 2);
+ unsigned i2 = scaled[3];
+ unsigned i3 = scaled[4];
+ unsigned i4 = scaled[5];
+ double f1 = i1, f2 = i2 * (0x1.0p-30), f3 = i3 * (0x1.0p-62), f4 = i4 * (0x1.0p-94);
+
+ /*
+ * Now f1+f2+f3+f4 is a representation, potentially to
+ * twice double precision, of 2^32 times ((2/pi)*x minus
+ * some integer). So our remaining job is to multiply
+ * back down by (pi/2)*2^-32, and convert back to one
+ * single-precision output number.
+ */
+ double ftop = f1 + (f2 + (f3 + f4));
+ ftop = __SET_LO(ftop, 0);
+ double fbot = f4 - (((ftop-f1)-f2)-f3);
+
+ /* ... and multiply by a prec-and-a-half value of (pi/2)*2^-32. */
+ double ret = (ftop * 0x1.921fb54p-32) + (ftop * 0x1.10b4611a62633p-62 + fbot * 0x1.921fb54442d18p-32);
+
+ /* Just before we return, take the input sign into account. */
+ if (__HI(x) & 0x80000000) {
+ q = -q;
+ ret = -ret;
+ }
+ y[0] = ret;
+ return q;
+ }
+}
diff --git a/math/single/funder.c b/math/single/funder.c
new file mode 100644
index 0000000..ef16f68
--- /dev/null
+++ b/math/single/funder.c
@@ -0,0 +1,51 @@
+/*
+ * funder.c - manually provoke SP exceptions for mathlib
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <fenv.h>
+#include "math_private.h"
+
+__inline float __mathlib_flt_infnan2(float x, float y)
+{
+ return x+y;
+}
+
+__inline float __mathlib_flt_infnan(float x)
+{
+ return x+x;
+}
+
+float __mathlib_flt_underflow(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_UNDERFLOW);
+#endif
+ return 0x1p-95F * 0x1p-95F;
+}
+
+float __mathlib_flt_overflow(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_OVERFLOW);
+#endif
+ return 0x1p+97F * 0x1p+97F;
+}
+
+float __mathlib_flt_invalid(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_INVALID);
+#endif
+ return 0.0f / 0.0f;
+}
+
+float __mathlib_flt_divzero(void)
+{
+#ifdef CLANG_EXCEPTIONS
+ feraiseexcept(FE_DIVBYZERO);
+#endif
+ return 1.0f / 0.0f;
+}
diff --git a/math/single/ieee_status.c b/math/single/ieee_status.c
new file mode 100644
index 0000000..ef846f4
--- /dev/null
+++ b/math/single/ieee_status.c
@@ -0,0 +1,38 @@
+/*
+ * ieee_status.c
+ *
+ * Copyright (c) 2015-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "math_private.h"
+
+__inline unsigned __ieee_status(unsigned bicmask, unsigned xormask)
+{
+#if defined __aarch64__ && defined __FP_FENV_EXCEPTIONS
+ unsigned status_word;
+ unsigned ret;
+
+#ifdef __FP_FENV_ROUNDING
+# define MASK (1<<27)|FE_IEEE_FLUSHZERO|FE_IEEE_MASK_ALL_EXCEPT|FE_IEEE_ALL_EXCEPT|FE_IEEE_ROUND_MASK
+#else
+# define MASK (1<<27)|FE_IEEE_FLUSHZERO|FE_IEEE_MASK_ALL_EXCEPT|FE_IEEE_ALL_EXCEPT
+#endif
+
+ /* mask out read-only bits */
+ bicmask &= MASK;
+ xormask &= MASK;
+
+ /* modify the status word */
+ __asm__ __volatile__ ("mrs %0, fpsr" : "=r" (status_word));
+ ret = status_word;
+ status_word &= ~bicmask;
+ status_word ^= xormask;
+ __asm__ __volatile__ ("msr fpsr, %0" : : "r" (status_word));
+
+ /* and return what it used to be */
+ return ret;
+#else
+ return 0;
+#endif
+}
diff --git a/math/single/math_private.h b/math/single/math_private.h
new file mode 100644
index 0000000..eef997d
--- /dev/null
+++ b/math/single/math_private.h
@@ -0,0 +1,138 @@
+/*
+ * math_private.h
+ *
+ * Copyright (c) 2015-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+/*
+ * Header file containing some definitions and other small reusable pieces of
+ * code that we need in the libraries.
+ */
+
+#ifndef __MATH_PRIVATE_H
+#define __MATH_PRIVATE_H
+
+#include <errno.h>
+#include <stdint.h>
+
+extern int __ieee754_rem_pio2(double, double *);
+extern double __kernel_poly(const double *, int, double);
+
+#define __FP_IEEE
+#define __FP_FENV_EXCEPTIONS
+#define __FP_FENV_ROUNDING
+#define __FP_INEXACT_EXCEPTION
+
+#define __set_errno(val) (errno = (val))
+
+static __inline uint32_t __LO(double x)
+{
+ union {double f; uint64_t i;} u = {x};
+ return (uint32_t)u.i;
+}
+
+static __inline uint32_t __HI(double x)
+{
+ union {double f; uint64_t i;} u = {x};
+ return u.i >> 32;
+}
+
+static __inline double __SET_LO(double x, uint32_t lo)
+{
+ union {double f; uint64_t i;} u = {x};
+ u.i = (u.i >> 32) << 32 | lo;
+ return u.f;
+}
+
+static __inline unsigned int fai(float f)
+{
+ union {float f; uint32_t i;} u = {f};
+ return u.i;
+}
+
+static __inline float fhex(unsigned int n)
+{
+ union {uint32_t i; float f;} u = {n};
+ return u.f;
+}
+
+#define CLEARBOTTOMHALF(x) fhex((fai(x) + 0x00000800) & 0xFFFFF000)
+
+#define FE_IEEE_OVERFLOW (0x00000004)
+#define FE_IEEE_UNDERFLOW (0x00000008)
+#define FE_IEEE_FLUSHZERO (0x01000000)
+#define FE_IEEE_ROUND_TONEAREST (0x00000000)
+#define FE_IEEE_ROUND_UPWARD (0x00400000)
+#define FE_IEEE_ROUND_DOWNWARD (0x00800000)
+#define FE_IEEE_ROUND_TOWARDZERO (0x00C00000)
+#define FE_IEEE_ROUND_MASK (0x00C00000)
+#define FE_IEEE_MASK_INVALID (0x00000100)
+#define FE_IEEE_MASK_DIVBYZERO (0x00000200)
+#define FE_IEEE_MASK_OVERFLOW (0x00000400)
+#define FE_IEEE_MASK_UNDERFLOW (0x00000800)
+#define FE_IEEE_MASK_INEXACT (0x00001000)
+#define FE_IEEE_MASK_INPUTDENORMAL (0x00008000)
+#define FE_IEEE_MASK_ALL_EXCEPT (0x00009F00)
+#define FE_IEEE_INVALID (0x00000001)
+#define FE_IEEE_DIVBYZERO (0x00000002)
+#define FE_IEEE_INEXACT (0x00000010)
+#define FE_IEEE_INPUTDENORMAL (0x00000080)
+#define FE_IEEE_ALL_EXCEPT (0x0000009F)
+
+extern double __mathlib_dbl_overflow(void);
+extern float __mathlib_flt_overflow(void);
+extern double __mathlib_dbl_underflow(void);
+extern float __mathlib_flt_underflow(void);
+extern double __mathlib_dbl_invalid(void);
+extern float __mathlib_flt_invalid(void);
+extern double __mathlib_dbl_divzero(void);
+extern float __mathlib_flt_divzero(void);
+#define DOUBLE_OVERFLOW ( __mathlib_dbl_overflow() )
+#define FLOAT_OVERFLOW ( __mathlib_flt_overflow() )
+#define DOUBLE_UNDERFLOW ( __mathlib_dbl_underflow() )
+#define FLOAT_UNDERFLOW ( __mathlib_flt_underflow() )
+#define DOUBLE_INVALID ( __mathlib_dbl_invalid() )
+#define FLOAT_INVALID ( __mathlib_flt_invalid() )
+#define DOUBLE_DIVZERO ( __mathlib_dbl_divzero() )
+#define FLOAT_DIVZERO ( __mathlib_flt_divzero() )
+
+extern float __mathlib_flt_infnan(float);
+extern float __mathlib_flt_infnan2(float, float);
+extern double __mathlib_dbl_infnan(double);
+extern double __mathlib_dbl_infnan2(double, double);
+extern unsigned __ieee_status(unsigned, unsigned);
+
+#define FLOAT_INFNAN(x) __mathlib_flt_infnan(x)
+#define FLOAT_INFNAN2(x,y) __mathlib_flt_infnan2(x,y)
+#define DOUBLE_INFNAN(x) __mathlib_dbl_infnan(x)
+#define DOUBLE_INFNAN2(x,y) __mathlib_dbl_infnan2(x,y)
+
+#define MATHERR_POWF_00(x,y) (__set_errno(EDOM), 1.0f)
+#define MATHERR_POWF_INF0(x,y) (__set_errno(EDOM), 1.0f)
+#define MATHERR_POWF_0NEG(x,y) (__set_errno(ERANGE), FLOAT_DIVZERO)
+#define MATHERR_POWF_NEG0FRAC(x,y) (0.0f)
+#define MATHERR_POWF_0NEGODD(x,y) (__set_errno(ERANGE), -FLOAT_DIVZERO)
+#define MATHERR_POWF_0NEGEVEN(x,y) (__set_errno(ERANGE), FLOAT_DIVZERO)
+#define MATHERR_POWF_NEGFRAC(x,y) (__set_errno(EDOM), FLOAT_INVALID)
+#define MATHERR_POWF_ONEINF(x,y) (1.0f)
+#define MATHERR_POWF_OFL(x,y,z) (__set_errno(ERANGE), copysignf(FLOAT_OVERFLOW,z))
+#define MATHERR_POWF_UFL(x,y,z) (__set_errno(ERANGE), copysignf(FLOAT_UNDERFLOW,z))
+
+#define MATHERR_LOGF_0(x) (__set_errno(ERANGE), -FLOAT_DIVZERO)
+#define MATHERR_LOGF_NEG(x) (__set_errno(EDOM), FLOAT_INVALID)
+
+#define MATHERR_SIN_INF(x) (__set_errno(EDOM), DOUBLE_INVALID)
+#define MATHERR_SINF_INF(x) (__set_errno(EDOM), FLOAT_INVALID)
+#define MATHERR_COS_INF(x) (__set_errno(EDOM), DOUBLE_INVALID)
+#define MATHERR_COSF_INF(x) (__set_errno(EDOM), FLOAT_INVALID)
+#define MATHERR_TAN_INF(x) (__set_errno(EDOM), DOUBLE_INVALID)
+#define MATHERR_TANF_INF(x) (__set_errno(EDOM), FLOAT_INVALID)
+
+#define MATHERR_EXPF_UFL(x) (__set_errno(ERANGE), FLOAT_UNDERFLOW)
+#define MATHERR_EXPF_OFL(x) (__set_errno(ERANGE), FLOAT_OVERFLOW)
+
+#define FLOAT_CHECKDENORM(x) ( (fpclassify(x) == FP_SUBNORMAL ? FLOAT_UNDERFLOW : 0), x )
+#define DOUBLE_CHECKDENORM(x) ( (fpclassify(x) == FP_SUBNORMAL ? DOUBLE_UNDERFLOW : 0), x )
+
+#endif /* __MATH_PRIVATE_H */
diff --git a/math/single/poly.c b/math/single/poly.c
new file mode 100644
index 0000000..4eaf7ff
--- /dev/null
+++ b/math/single/poly.c
@@ -0,0 +1,25 @@
+/*
+ * poly.c
+ *
+ * Copyright (c) 1998-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+double __kernel_poly(const double *coeffs, int n, double x)
+{
+ double result = coeffs[--n];
+
+ while ((n & ~0x6) != 0) /* Loop until n even and < 8 */
+ result = (result * x) + coeffs[--n];
+
+ switch (n)
+ {
+ case 6: result = (result * x) + coeffs[5];
+ result = (result * x) + coeffs[4];
+ case 4: result = (result * x) + coeffs[3];
+ result = (result * x) + coeffs[2];
+ case 2: result = (result * x) + coeffs[1];
+ result = (result * x) + coeffs[0];
+ }
+ return result;
+}
diff --git a/math/single/rredf.c b/math/single/rredf.c
new file mode 100644
index 0000000..a5c3122
--- /dev/null
+++ b/math/single/rredf.c
@@ -0,0 +1,239 @@
+/*
+ * rredf.c - trigonometric range reduction function
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+/*
+ * This code is intended to be used as the second half of a range
+ * reducer whose first half is an inline function defined in
+ * rredf.h. Each trig function performs range reduction by invoking
+ * that, which handles the quickest and most common cases inline
+ * before handing off to this function for everything else. Thus a
+ * reasonable compromise is struck between speed and space. (I
+ * hope.) In particular, this approach avoids a function call
+ * overhead in the common case.
+ */
+
+#include "math_private.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Input values to this function:
+ * - x is the original user input value, unchanged by the
+ * first-tier reducer in the case where it hands over to us.
+ * - q is still the place where the caller expects us to leave the
+ * quadrant code.
+ * - k is the IEEE bit pattern of x (which it would seem a shame to
+ * recompute given that the first-tier reducer already went to
+ * the effort of extracting it from the VFP). FIXME: in softfp,
+ * on the other hand, it's unconscionably wasteful to replicate
+ * this value into a second register and we should change the
+ * prototype!
+ */
+float __mathlib_rredf2(float x, int *q, unsigned k)
+{
+ /*
+ * First, weed out infinities and NaNs, and deal with them by
+ * returning a negative q.
+ */
+ if ((k << 1) >= 0xFF000000) {
+ *q = -1;
+ return x;
+ }
+ /*
+ * We do general range reduction by multiplying by 2/pi, and
+ * retaining the bottom two bits of the integer part and an
+ * initial chunk of the fraction below that. The integer bits
+ * are directly output as *q; the fraction is then multiplied
+ * back up by pi/2 before returning it.
+ *
+ * To get this right, we don't have to multiply by the _whole_
+ * of 2/pi right from the most significant bit downwards:
+ * instead we can discard any bit of 2/pi with a place value
+ * high enough that multiplying it by the LSB of x will yield a
+ * place value higher than 2. Thus we can bound the required
+ * work by a reasonably small constant regardless of the size of
+ * x (unlike, for instance, the IEEE remainder operation).
+ *
+ * At the other end, however, we must take more care: it isn't
+ * adequate just to acquire two integer bits and 24 fraction
+ * bits of (2/pi)x, because if a lot of those fraction bits are
+ * zero then we will suffer significance loss. So we must keep
+ * computing fraction bits as far down as 23 bits below the
+ * _highest set fraction bit_.
+ *
+ * The immediate question, therefore, is what the bound on this
+ * end of the job will be. In other words: what is the smallest
+ * difference between an integer multiple of pi/2 and a
+ * representable IEEE single precision number larger than the
+ * maximum size handled by rredf.h?
+ *
+ * The most difficult cases for each exponent can readily be
+ * found by Tim Peters's modular minimisation algorithm, and are
+ * tabulated in mathlib/tests/directed/rredf.tst. The single
+ * worst case is the IEEE single-precision number 0x6F79BE45,
+ * whose numerical value is in the region of 7.7*10^28; when
+ * reduced mod pi/2, it attains the value 0x30DDEEA9, or about
+ * 0.00000000161. The highest set bit of this value is the one
+ * with place value 2^-30; so its lowest is 2^-53. Hence, to be
+ * sure of having enough fraction bits to output at full single
+ * precision, we must be prepared to collect up to 53 bits of
+ * fraction in addition to our two bits of integer part.
+ *
+ * To begin with, this means we must store the value of 2/pi to
+ * a precision of 128+53 = 181 bits. That's six 32-bit words.
+ * (Hardly a chore, unlike the equivalent problem in double
+ * precision!)
+ */
+ {
+ static const unsigned twooverpi[] = {
+ /* We start with a zero word, because that takes up less
+ * space than the array bounds checking and special-case
+ * handling that would have to occur in its absence. */
+ 0,
+ /* 2/pi in hex is 0.a2f9836e... */
+ 0xa2f9836e, 0x4e441529, 0xfc2757d1,
+ 0xf534ddc0, 0xdb629599, 0x3c439041,
+ /* Again, to avoid array bounds overrun, we store a spare
+ * word at the end. And it would be a shame to fill it
+ * with zeroes when we could use more bits of 2/pi... */
+ 0xfe5163ab
+ };
+
+ /*
+ * Multiprecision multiplication of this nature is more
+ * readily done in integers than in VFP, since we can use
+ * UMULL (on CPUs that support it) to multiply 32 by 32 bits
+ * at a time whereas the VFP would only be able to do 12x12
+ * without losing accuracy.
+ *
+ * So extract the mantissa of the input number as a 32-bit
+ * integer.
+ */
+ unsigned mantissa = 0x80000000 | (k << 8);
+
+ /*
+ * Now work out which part of our stored value of 2/pi we're
+ * supposed to be multiplying by.
+ *
+ * Let the IEEE exponent field of x be e. With its bias
+ * removed, (e-127) is the index of the set bit at the top
+ * of 'mantissa' (i.e. that set bit has real place value
+ * 2^(e-127)). So the lowest set bit in 'mantissa', 23 bits
+ * further down, must have place value 2^(e-150).
+ *
+ * We begin taking an interest in the value of 2/pi at the
+ * bit which multiplies by _that_ to give something with
+ * place value at most 2. In other words, the highest bit of
+ * 2/pi we're interested in is the one with place value
+ * 2/(2^(e-150)) = 2^(151-e).
+ *
+ * The bit at the top of the first (zero) word of the above
+ * array has place value 2^31. Hence, the bit we want to put
+ * at the top of the first word we extract from that array
+ * is the one at bit index n, where 31-n = 151-e and hence
+ * n=e-120.
+ */
+ int topbitindex = ((k >> 23) & 0xFF) - 120;
+ int wordindex = topbitindex >> 5;
+ int shiftup = topbitindex & 31;
+ int shiftdown = 32 - shiftup;
+ unsigned word1, word2, word3;
+ if (shiftup) {
+ word1 = (twooverpi[wordindex] << shiftup) | (twooverpi[wordindex+1] >> shiftdown);
+ word2 = (twooverpi[wordindex+1] << shiftup) | (twooverpi[wordindex+2] >> shiftdown);
+ word3 = (twooverpi[wordindex+2] << shiftup) | (twooverpi[wordindex+3] >> shiftdown);
+ } else {
+ word1 = twooverpi[wordindex];
+ word2 = twooverpi[wordindex+1];
+ word3 = twooverpi[wordindex+2];
+ }
+
+ /*
+ * Do the multiplications, and add them together.
+ */
+ unsigned long long mult1 = (unsigned long long)word1 * mantissa;
+ unsigned long long mult2 = (unsigned long long)word2 * mantissa;
+ unsigned long long mult3 = (unsigned long long)word3 * mantissa;
+
+ unsigned /* bottom3 = (unsigned)mult3, */ top3 = (unsigned)(mult3 >> 32);
+ unsigned bottom2 = (unsigned)mult2, top2 = (unsigned)(mult2 >> 32);
+ unsigned bottom1 = (unsigned)mult1, top1 = (unsigned)(mult1 >> 32);
+
+ unsigned out3, out2, out1, carry;
+
+ out3 = top3 + bottom2; carry = (out3 < top3);
+ out2 = top2 + bottom1 + carry; carry = carry ? (out2 <= top2) : (out2 < top2);
+ out1 = top1 + carry;
+
+ /*
+ * The two words we multiplied to get mult1 had their top
+ * bits at (respectively) place values 2^(151-e) and
+ * 2^(e-127). The value of those two bits multiplied
+ * together will have ended up in bit 62 (the
+ * topmost-but-one bit) of mult1, i.e. bit 30 of out1.
+ * Hence, that bit has place value 2^(151-e+e-127) = 2^24.
+ * So the integer value that we want to output as q,
+ * consisting of the bits with place values 2^1 and 2^0,
+ * must be 23 and 24 bits below that, i.e. in bits 7 and 6
+ * of out1.
+ *
+ * Or, at least, it will be once we add 1/2, to round to the
+ * _nearest_ multiple of pi/2 rather than the next one down.
+ */
+ *q = (out1 + (1<<5)) >> 6;
+
+ /*
+ * Now we construct the output fraction, which is most
+ * simply done in the VFP. We just extract three consecutive
+ * bit strings from our chunk of binary data, convert them
+ * to integers, equip each with an appropriate FP exponent,
+ * add them together, and (don't forget) multiply back up by
+ * pi/2. That way we don't have to work out ourselves where
+ * the highest fraction bit ended up.
+ *
+ * Since our displacement from the nearest multiple of pi/2
+ * can be positive or negative, the topmost of these three
+ * values must be arranged with its 2^-1 bit at the very top
+ * of the word, and then treated as a _signed_ integer.
+ */
+ {
+ int i1 = (out1 << 26) | ((out2 >> 19) << 13);
+ unsigned i2 = out2 << 13;
+ unsigned i3 = out3;
+ float f1 = i1, f2 = i2 * (1.0f/524288.0f), f3 = i3 * (1.0f/524288.0f/524288.0f);
+
+ /*
+ * Now f1+f2+f3 is a representation, potentially to
+ * twice double precision, of 2^32 times ((2/pi)*x minus
+ * some integer). So our remaining job is to multiply
+ * back down by (pi/2)*2^-32, and convert back to one
+ * single-precision output number.
+ */
+
+ /* Normalise to a prec-and-a-half representation... */
+ float ftop = CLEARBOTTOMHALF(f1+f2+f3), fbot = f3-((ftop-f1)-f2);
+
+ /* ... and multiply by a prec-and-a-half value of (pi/2)*2^-32. */
+ float ret = (ftop * 0x1.92p-32F) + (ftop * 0x1.fb5444p-44F + fbot * 0x1.921fb6p-32F);
+
+ /* Just before we return, take the input sign into account. */
+ if (k & 0x80000000) {
+ *q = 0x10000000 - *q;
+ ret = -ret;
+ }
+ return ret;
+ }
+ }
+}
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif /* __cplusplus */
+
+/* end of rredf.c */
diff --git a/math/single/rredf.h b/math/single/rredf.h
new file mode 100644
index 0000000..41d3a0c
--- /dev/null
+++ b/math/single/rredf.h
@@ -0,0 +1,146 @@
+/*
+ * rredf.h - trigonometric range reduction function written new for RVCT 4.1
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+/*
+ * This header file defines an inline function which all three of
+ * the single-precision trig functions (sinf, cosf, tanf) should use
+ * to perform range reduction. The inline function handles the
+ * quickest and most common cases inline, before handing off to an
+ * out-of-line function defined in rredf.c for everything else. Thus
+ * a reasonable compromise is struck between speed and space. (I
+ * hope.) In particular, this approach avoids a function call
+ * overhead in the common case.
+ */
+
+#ifndef _included_rredf_h
+#define _included_rredf_h
+
+#include "math_private.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern float __mathlib_rredf2(float x, int *q, unsigned k);
+
+/*
+ * Semantics of the function:
+ * - x is the single-precision input value provided by the user
+ * - the return value is in the range [-pi/4,pi/4], and is equal
+ * (within reasonable accuracy bounds) to x minus n*pi/2 for some
+ * integer n. (FIXME: perhaps some slippage on the output
+ * interval is acceptable, requiring more range from the
+ * following polynomial approximations but permitting more
+ * approximate rred decisions?)
+ * - *q is set to a positive value whose low two bits match those
+ * of n. Alternatively, it comes back as -1 indicating that the
+ * input value was trivial in some way (infinity, NaN, or so
+ * small that we can safely return sin(x)=tan(x)=x,cos(x)=1).
+ */
+static __inline float __mathlib_rredf(float x, int *q)
+{
+ /*
+ * First, extract the bit pattern of x as an integer, so that we
+ * can repeatedly compare things to it without multiple
+ * overheads in retrieving comparison results from the VFP.
+ */
+ unsigned k = fai(x);
+
+ /*
+ * Deal immediately with the simplest possible case, in which x
+ * is already within the interval [-pi/4,pi/4]. This also
+ * identifies the subcase of ludicrously small x.
+ */
+ if ((k << 1) < (0x3f490fdb << 1)) {
+ if ((k << 1) < (0x39800000 << 1))
+ *q = -1;
+ else
+ *q = 0;
+ return x;
+ }
+
+ /*
+ * The next plan is to multiply x by 2/pi and convert to an
+ * integer, which gives us n; then we subtract n*pi/2 from x to
+ * get our output value.
+ *
+ * By representing pi/2 in that final step by a prec-and-a-half
+ * approximation, we can arrange good accuracy for n strictly
+ * less than 2^13 (so that an FP representation of n has twelve
+ * zero bits at the bottom). So our threshold for this strategy
+ * is 2^13 * pi/2 - pi/4, otherwise known as 8191.75 * pi/2 or
+ * 4095.875*pi. (Or, for those perverse people interested in
+ * actual numbers rather than multiples of pi/2, about 12867.5.)
+ */
+ if (__builtin_expect((k & 0x7fffffff) < 0x46490e49, 1)) {
+ float nf = 0.636619772367581343f * x;
+ /*
+ * The difference between that single-precision constant and
+ * the real 2/pi is about 2.568e-8. Hence the product nf has a
+ * potential error of 2.568e-8|x| even before rounding; since
+ * |x| < 4096 pi, that gives us an error bound of about
+ * 0.0003305.
+ *
+ * nf is then rounded to single precision, with a max error of
+ * 1/2 ULP, and since nf goes up to just under 8192, half a
+ * ULP could be as big as 2^-12 ~= 0.0002441.
+ *
+ * So by the time we convert nf to an integer, it could be off
+ * by that much, causing the wrong integer to be selected, and
+ * causing us to return a value a little bit outside the
+ * theoretical [-pi/4,+pi/4] output interval.
+ *
+ * How much outside? Well, we subtract nf*pi/2 from x, so the
+ * error bounds above have be be multiplied by pi/2. And if
+ * both of the above sources of error suffer their worst cases
+ * at once, then the very largest value we could return is
+ * obtained by adding that lot to the interval bound pi/4 to
+ * get
+ *
+ * pi/4 + ((2/pi - 0f_3f22f983)*4096*pi + 2^-12) * pi/2
+ *
+ * which comes to 0f_3f494b02. (Compare 0f_3f490fdb = pi/4.)
+ *
+ * So callers of this range reducer should be prepared to
+ * handle numbers up to that large.
+ */
+#ifdef __TARGET_FPU_SOFTVFP
+ nf = _frnd(nf);
+#else
+ if (k & 0x80000000)
+ nf = (nf - 8388608.0f) + 8388608.0f;
+ else
+ nf = (nf + 8388608.0f) - 8388608.0f; /* round to _nearest_ integer. FIXME: use some sort of frnd in softfp */
+#endif
+ *q = 3 & (int)nf;
+#if 0
+ /*
+ * FIXME: now I need a bunch of special cases to avoid
+ * having to do the full four-word reduction every time.
+ * Also, adjust the comment at the top of this section!
+ */
+ if (__builtin_expect((k & 0x7fffffff) < 0x46490e49, 1))
+ return ((x - nf * 0x1.92p+0F) - nf * 0x1.fb4p-12F) - nf * 0x1.4442d2p-24F;
+ else
+#endif
+ return ((x - nf * 0x1.92p+0F) - nf * 0x1.fb4p-12F) - nf * 0x1.444p-24F - nf * 0x1.68c234p-39F;
+ }
+
+ /*
+ * That's enough to do in-line; if we're still playing, hand off
+ * to the out-of-line main range reducer.
+ */
+ return __mathlib_rredf2(x, q, k);
+}
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif /* __cplusplus */
+
+#endif /* included */
+
+/* end of rredf.h */
diff --git a/math/single/s_cosf.c b/math/single/s_cosf.c
new file mode 100644
index 0000000..0e40b52
--- /dev/null
+++ b/math/single/s_cosf.c
@@ -0,0 +1,11 @@
+/*
+ * s_cosf.c - single precision cosine function
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+#define COSINE
+#include "s_sincosf.c"
+
+/* end of s_cosf.c */
diff --git a/math/single/s_sincosf.c b/math/single/s_sincosf.c
new file mode 100644
index 0000000..38a8511
--- /dev/null
+++ b/math/single/s_sincosf.c
@@ -0,0 +1,109 @@
+/*
+ * s_sincosf.c - single precision sine and cosine functions
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+/*
+ * Source: my own head, and Remez-generated polynomial approximations.
+ */
+
+#include <fenv.h>
+#include <math.h>
+#include <errno.h>
+#include "rredf.h"
+#include "math_private.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef COSINE
+#define FUNCNAME sinf
+#define SOFTFP_FUNCNAME __softfp_sinf
+#define DO_SIN (!(q & 1))
+#define NEGATE_SIN ((q & 2))
+#define NEGATE_COS ((q & 2))
+#define TRIVIAL_RESULT(x) FLOAT_CHECKDENORM(x)
+#define ERR_INF MATHERR_SINF_INF
+#else
+#define FUNCNAME cosf
+#define SOFTFP_FUNCNAME __softfp_cosf
+#define DO_SIN (q & 1)
+#define NEGATE_SIN (!(q & 2))
+#define NEGATE_COS ((q & 2))
+#define TRIVIAL_RESULT(x) 1.0f
+#define ERR_INF MATHERR_COSF_INF
+#endif
+
+float FUNCNAME(float x)
+{
+ int q;
+
+ /*
+ * Range-reduce x to the range [-pi/4,pi/4].
+ */
+ {
+ /*
+ * I enclose the call to __mathlib_rredf in braces so that
+ * the address-taken-ness of qq does not propagate
+ * throughout the rest of the function, for what that might
+ * be worth.
+ */
+ int qq;
+ x = __mathlib_rredf(x, &qq);
+ q = qq;
+ }
+ if (__builtin_expect(q < 0, 0)) { /* this signals tiny, inf, or NaN */
+ unsigned k = fai(x) << 1;
+ if (k < 0xFF000000) /* tiny */
+ return TRIVIAL_RESULT(x);
+ else if (k == 0xFF000000) /* inf */
+ return ERR_INF(x);
+ else /* NaN */
+ return FLOAT_INFNAN(x);
+ }
+
+ /*
+ * Depending on the quadrant we were in, we may have to compute
+ * a sine-like function (f(0)=0) or a cosine-like one (f(0)=1),
+ * and we may have to negate it.
+ */
+ if (DO_SIN) {
+ float x2 = x*x;
+ /*
+ * Coefficients generated by the command
+
+./auxiliary/remez.jl --variable=x2 --suffix=f -- '0' 'atan(BigFloat(1))^2' 2 0 'x==0 ? -1/BigFloat(6) : (x->(sin(x)-x)/x^3)(sqrt(x))' 'sqrt(x^3)'
+
+ */
+ x += x * (x2 * (
+ -1.666665066929417292436220415142244613956015227491999719404711781344783392564922e-01f+x2*(8.331978663157089651408875887703995477889496917296385733254577121461421466427772e-03f+x2*(-1.949563623766929906511886482584265500187314705496861877317774185883215997931494e-04f))
+ ));
+ if (NEGATE_SIN)
+ x = -x;
+ return x;
+ } else {
+ float x2 = x*x;
+ /*
+ * Coefficients generated by the command
+
+./auxiliary/remez.jl --variable=x2 --suffix=f -- '0' 'atan(BigFloat(1))^2' 2 0 'x==0 ? -1/BigFloat(6) : (x->(cos(x)-1)/x^2)(sqrt(x))' 'x'
+
+ */
+ x = 1.0f + x2*(
+ -4.999989478137016757327030935768632852012781143541026304540837816323349768666875e-01f+x2*(4.165629457842617238353362092016541041535652603456375154392942188742496860024377e-02f+x2*(-1.35978231111049428748566568960423202948250988565693107969571193763372093404347e-03f))
+ );
+ if (NEGATE_COS)
+ x = -x;
+ return x;
+ }
+}
+
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif /* __cplusplus */
+
+/* end of sincosf.c */
diff --git a/math/single/s_sinf.c b/math/single/s_sinf.c
new file mode 100644
index 0000000..ab0f628
--- /dev/null
+++ b/math/single/s_sinf.c
@@ -0,0 +1,11 @@
+/*
+ * s_sinf.c - single precision sine function
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+#define SINE
+#include "s_sincosf.c"
+
+/* end of s_sinf.c */
diff --git a/math/single/s_tanf.c b/math/single/s_tanf.c
new file mode 100644
index 0000000..0e13d95
--- /dev/null
+++ b/math/single/s_tanf.c
@@ -0,0 +1,77 @@
+/*
+ * s_tanf.c - single precision tangent function
+ *
+ * Copyright (c) 2009-2018, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+/*
+ * Source: my own head, and Remez-generated polynomial approximations.
+ */
+
+#include <math.h>
+#include "math_private.h"
+#include <errno.h>
+#include <fenv.h>
+#include "rredf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+float tanf(float x)
+{
+ int q;
+
+ /*
+ * Range-reduce x to the range [-pi/4,pi/4].
+ */
+ {
+ /*
+ * I enclose the call to __mathlib_rredf in braces so that
+ * the address-taken-ness of qq does not propagate
+ * throughout the rest of the function, for what that might
+ * be worth.
+ */
+ int qq;
+ x = __mathlib_rredf(x, &qq);
+ q = qq;
+ }
+ if (__builtin_expect(q < 0, 0)) { /* this signals tiny, inf, or NaN */
+ unsigned k = fai(x) << 1;
+ if (k < 0xFF000000) /* tiny */
+ return FLOAT_CHECKDENORM(x);
+ else if (k == 0xFF000000) /* inf */
+ return MATHERR_TANF_INF(x);
+ else /* NaN */
+ return FLOAT_INFNAN(x);
+ }
+
+ /*
+ * We use a direct polynomial approximation for tan(x) on
+ * [-pi/4,pi/4], and then take the negative reciprocal of the
+ * result if we're in an interval surrounding an odd rather than
+ * even multiple of pi/2.
+ *
+ * Coefficients generated by the command
+
+./auxiliary/remez.jl --variable=x2 --suffix=f -- '0' '(pi/BigFloat(4))^2' 5 0 'x==0 ? 1/BigFloat(3) : (tan(sqrt(x))-sqrt(x))/sqrt(x^3)' 'sqrt(x^3)'
+
+ */
+ {
+ float x2 = x*x;
+ x += x * (x2 * (
+ 3.333294809182307633621540045249152105330074691488121206914336806061620616979305e-01f+x2*(1.334274588580033216191949445078951865160600494428914956688702429547258497367525e-01f+x2*(5.315177279765676178198868818834880279286012428084733419724267810723468887753723e-02f+x2*(2.520300881849204519070372772571624013984546591252791443673871814078418474596388e-02f+x2*(2.051177187082974766686645514206648277055233230110624602600687812103764075834307e-03f+x2*(9.943421494628597182458186353995299429948224864648292162238582752158235742046109e-03f)))))
+ ));
+ if (q & 1)
+ x = -1.0f/x;
+
+ return x;
+ }
+}
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif /* __cplusplus */
+
+/* end of s_tanf.c */
diff --git a/math/tanf.c b/math/tanf.c
new file mode 100644
index 0000000..d3799f5
--- /dev/null
+++ b/math/tanf.c
@@ -0,0 +1,3 @@
+#if WANT_SINGLEPREC
+#include "single/s_tanf.c"
+#endif
diff --git a/math/test/runulp.sh b/math/test/runulp.sh
deleted file mode 100755
index d7d79a4..0000000
--- a/math/test/runulp.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/bash
-
-# ULP error check script.
-#
-# Copyright (c) 2019, Arm Limited.
-# SPDX-License-Identifier: MIT
-
-#set -x
-set -eu
-
-# cd to bin directory.
-cd "${0%/*}"
-
-rmodes='n u d z'
-#rmodes=n
-flags='-q'
-emu="$@"
-
-t() {
- [ $r = "n" ] && Lt=$L || Lt=$Ldir
- $emu ./ulp -r $r -e $Lt $flags "$@"
-}
-
-Ldir=0.5
-for r in $rmodes
-do
-L=0.01
-t exp 0 0xffff000000000000 10000
-t exp 0x1p-6 0x1p6 40000
-t exp -0x1p-6 -0x1p6 40000
-t exp 633.3 733.3 10000
-t exp -633.3 -777.3 10000
-
-L=0.01
-t exp2 0 0xffff000000000000 10000
-t exp2 0x1p-6 0x1p6 40000
-t exp2 -0x1p-6 -0x1p6 40000
-t exp2 633.3 733.3 10000
-t exp2 -633.3 -777.3 10000
-
-L=0.05
-t pow 0.5 2.0 x 0 inf 20000
-t pow -0.5 -2.0 x 0 inf 20000
-t pow 0.5 2.0 x -0 -inf 20000
-t pow -0.5 -2.0 x -0 -inf 20000
-t pow 0.5 2.0 x 0x1p-10 0x1p10 40000
-t pow 0.5 2.0 x -0x1p-10 -0x1p10 40000
-t pow 0 inf x 0.5 2.0 80000
-t pow 0 inf x -0.5 -2.0 80000
-t pow 0x1.fp-1 0x1.08p0 x 0x1p8 0x1p17 80000
-t pow 0x1.fp-1 0x1.08p0 x -0x1p8 -0x1p17 80000
-t pow 0 0x1p-1000 x 0 1.0 50000
-t pow 0x1p1000 inf x 0 1.0 50000
-t pow 0x1.ffffffffffff0p-1 0x1.0000000000008p0 x 0x1p60 0x1p68 50000
-t pow 0x1.ffffffffff000p-1 0x1p0 x 0x1p50 0x1p52 50000
-t pow -0x1.ffffffffff000p-1 -0x1p0 x 0x1p50 0x1p52 50000
-
-L=0.01
-t expf 0 0xffff0000 10000
-t expf 0x1p-14 0x1p8 50000
-t expf -0x1p-14 -0x1p8 50000
-
-L=0.01
-t exp2f 0 0xffff0000 10000
-t exp2f 0x1p-14 0x1p8 50000
-t exp2f -0x1p-14 -0x1p8 50000
-
-L=0.06
-t sinf 0 0xffff0000 10000
-t sinf 0x1p-14 0x1p54 50000
-t sinf -0x1p-14 -0x1p54 50000
-
-L=0.06
-t cosf 0 0xffff0000 10000
-t cosf 0x1p-14 0x1p54 50000
-t cosf -0x1p-14 -0x1p54 50000
-
-L=0.4
-t powf 0x1p-1 0x1p1 x 0x1p-7 0x1p7 50000
-t powf 0x1p-1 0x1p1 x -0x1p-7 -0x1p7 50000
-t powf 0x1p-70 0x1p70 x 0x1p-1 0x1p1 50000
-t powf 0x1p-70 0x1p70 x -0x1p-1 -0x1p1 50000
-t powf 0x1.ep-1 0x1.1p0 x 0x1p8 0x1p14 50000
-t powf 0x1.ep-1 0x1.1p0 x -0x1p8 -0x1p14 50000
-done
diff --git a/math/test/ulp.c b/math/test/ulp.c
deleted file mode 100644
index 8782fb0..0000000
--- a/math/test/ulp.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * ULP error checking tool for math functions.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <ctype.h>
-#include <fenv.h>
-#include <float.h>
-#include <math.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Don't depend on mpfr by default. */
-#ifndef USE_MPFR
-# define USE_MPFR 0
-#endif
-#if USE_MPFR
-# include <mpfr.h>
-#endif
-
-static inline uint64_t
-asuint64 (double f)
-{
- union
- {
- double f;
- uint64_t i;
- } u = {f};
- return u.i;
-}
-
-static inline double
-asdouble (uint64_t i)
-{
- union
- {
- uint64_t i;
- double f;
- } u = {i};
- return u.f;
-}
-
-static inline uint32_t
-asuint (float f)
-{
- union
- {
- float f;
- uint32_t i;
- } u = {f};
- return u.i;
-}
-
-static inline float
-asfloat (uint32_t i)
-{
- union
- {
- uint32_t i;
- float f;
- } u = {i};
- return u.f;
-}
-
-static uint64_t seed = 0x0123456789abcdef;
-static uint64_t
-rand64 (void)
-{
- seed = 6364136223846793005ull * seed + 1;
- return seed ^ (seed >> 32);
-}
-
-/* Uniform random in [0,n]. */
-static uint64_t
-randn (uint64_t n)
-{
- uint64_t r, m;
-
- if (n == 0)
- return 0;
- n++;
- if (n == 0)
- return rand64 ();
- for (;;)
- {
- r = rand64 ();
- m = r % n;
- if (r - m <= -n)
- return m;
- }
-}
-
-struct gen
-{
- uint64_t start;
- uint64_t len;
- uint64_t start2;
- uint64_t len2;
- uint64_t off;
- uint64_t step;
- uint64_t cnt;
-};
-
-struct args_f1
-{
- float x;
-};
-
-struct args_f2
-{
- float x;
- float x2;
-};
-
-struct args_d1
-{
- double x;
-};
-
-struct args_d2
-{
- double x;
- double x2;
-};
-
-/* result = y + tail*2^ulpexp. */
-struct ret_f
-{
- float y;
- double tail;
- int ulpexp;
- int ex;
- int ex_may;
-};
-
-struct ret_d
-{
- double y;
- double tail;
- int ulpexp;
- int ex;
- int ex_may;
-};
-
-static inline uint64_t
-next1 (struct gen *g)
-{
- /* For single argument use randomized incremental steps,
- that produce dense sampling without collisions and allow
- testing all inputs in a range. */
- uint64_t r = g->start + g->off;
- g->off += g->step + randn (g->step / 2);
- if (g->off > g->len)
- g->off -= g->len; /* hack. */
- return r;
-}
-
-static inline uint64_t
-next2 (uint64_t *x2, struct gen *g)
-{
- /* For two arguments use uniform random sampling. */
- uint64_t r = g->start + randn (g->len);
- *x2 = g->start2 + randn (g->len2);
- return r;
-}
-
-static struct args_f1
-next_f1 (void *g)
-{
- return (struct args_f1){asfloat (next1 (g))};
-}
-
-static struct args_f2
-next_f2 (void *g)
-{
- uint64_t x2;
- uint64_t x = next2 (&x2, g);
- return (struct args_f2){asfloat (x), asfloat (x2)};
-}
-
-static struct args_d1
-next_d1 (void *g)
-{
- return (struct args_d1){asdouble (next1 (g))};
-}
-
-static struct args_d2
-next_d2 (void *g)
-{
- uint64_t x2;
- uint64_t x = next2 (&x2, g);
- return (struct args_d2){asdouble (x), asdouble (x2)};
-}
-
-struct conf
-{
- int r;
- int rc;
- int quiet;
- int mpfr;
- int fenv;
- unsigned long long n;
- double softlim;
- double errlim;
-};
-
-struct fun
-{
- const char *name;
- int arity;
- int singleprec;
- union
- {
- float (*f1) (float);
- float (*f2) (float, float);
- double (*d1) (double);
- double (*d2) (double, double);
- } fun;
- union
- {
- double (*f1) (double);
- double (*f2) (double, double);
- long double (*d1) (long double);
- long double (*d2) (long double, long double);
- } fun_long;
-#if USE_MPFR
- union
- {
- int (*f1) (mpfr_t, const mpfr_t, mpfr_rnd_t);
- int (*f2) (mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t);
- int (*d1) (mpfr_t, const mpfr_t, mpfr_rnd_t);
- int (*d2) (mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t);
- } fun_mpfr;
-#endif
-};
-
-static const struct fun fun[] = {
-#if USE_MPFR
-# define F(x, x_long, x_mpfr, a, s, t) \
- {#x, a, s, {.t = x}, {.t = x_long}, {.t = x_mpfr}},
-#else
-# define F(x, x_long, x_mpfr, a, s, t) \
- {#x, a, s, {.t = x}, {.t = x_long}},
-#endif
-#define F1(x) F (x##f, x, mpfr_##x, 1, 1, f1)
-#define F2(x) F (x##f, x, mpfr_##x, 2, 1, f2)
-#define D1(x) F (x, x##l, mpfr_##x, 1, 0, d1)
-#define D2(x) F (x, x##l, mpfr_##x, 2, 0, d2)
- F1 (sin)
- F1 (cos)
- F1 (exp)
- F1 (exp2)
- F1 (log)
- F1 (log2)
- F2 (pow)
- D1 (exp)
- D1 (exp2)
- D1 (log)
- D1 (log2)
- D2 (pow)
- {0}};
-
-/* Boilerplate for generic calls. */
-
-static inline int
-ulpscale_f (float x)
-{
- int e = asuint (x) >> 23 & 0xff;
- if (!e)
- e++;
- return e - 0x7f - 23;
-}
-static inline int
-ulpscale_d (double x)
-{
- int e = asuint64 (x) >> 52 & 0x7ff;
- if (!e)
- e++;
- return e - 0x3ff - 52;
-}
-static inline float
-call_f1 (const struct fun *f, struct args_f1 a)
-{
- return f->fun.f1 (a.x);
-}
-static inline float
-call_f2 (const struct fun *f, struct args_f2 a)
-{
- return f->fun.f2 (a.x, a.x2);
-}
-
-static inline double
-call_d1 (const struct fun *f, struct args_d1 a)
-{
- return f->fun.d1 (a.x);
-}
-static inline double
-call_d2 (const struct fun *f, struct args_d2 a)
-{
- return f->fun.d2 (a.x, a.x2);
-}
-static inline double
-call_long_f1 (const struct fun *f, struct args_f1 a)
-{
- return f->fun_long.f1 (a.x);
-}
-static inline double
-call_long_f2 (const struct fun *f, struct args_f2 a)
-{
- return f->fun_long.f2 (a.x, a.x2);
-}
-static inline long double
-call_long_d1 (const struct fun *f, struct args_d1 a)
-{
- return f->fun_long.d1 (a.x);
-}
-static inline long double
-call_long_d2 (const struct fun *f, struct args_d2 a)
-{
- return f->fun_long.d2 (a.x, a.x2);
-}
-static inline void
-printcall_f1 (const struct fun *f, struct args_f1 a)
-{
- printf ("%s(%a)", f->name, a.x);
-}
-static inline void
-printcall_f2 (const struct fun *f, struct args_f2 a)
-{
- printf ("%s(%a, %a)", f->name, a.x, a.x2);
-}
-static inline void
-printcall_d1 (const struct fun *f, struct args_d1 a)
-{
- printf ("%s(%a)", f->name, a.x);
-}
-static inline void
-printcall_d2 (const struct fun *f, struct args_d2 a)
-{
- printf ("%s(%a, %a)", f->name, a.x, a.x2);
-}
-static inline void
-printgen_f1 (const struct fun *f, struct gen *gen)
-{
- printf ("%s in [%a;%a]", f->name, asfloat (gen->start),
- asfloat (gen->start + gen->len));
-}
-static inline void
-printgen_f2 (const struct fun *f, struct gen *gen)
-{
- printf ("%s in [%a;%a] x [%a;%a]", f->name, asfloat (gen->start),
- asfloat (gen->start + gen->len), asfloat (gen->start2),
- asfloat (gen->start2 + gen->len2));
-}
-static inline void
-printgen_d1 (const struct fun *f, struct gen *gen)
-{
- printf ("%s in [%a;%a]", f->name, asdouble (gen->start),
- asdouble (gen->start + gen->len));
-}
-static inline void
-printgen_d2 (const struct fun *f, struct gen *gen)
-{
- printf ("%s in [%a;%a] x [%a;%a]", f->name, asdouble (gen->start),
- asdouble (gen->start + gen->len), asdouble (gen->start2),
- asdouble (gen->start2 + gen->len2));
-}
-
-#define reduce_f1(a, f, op) (f (a.x))
-#define reduce_f2(a, f, op) (f (a.x) op f (a.x2))
-#define reduce_d1(a, f, op) (f (a.x))
-#define reduce_d2(a, f, op) (f (a.x) op f (a.x2))
-
-#ifndef IEEE_754_2008_SNAN
-# define IEEE_754_2008_SNAN 1
-#endif
-static inline int
-issignaling_f (float x)
-{
- uint32_t ix = asuint (x);
- if (!IEEE_754_2008_SNAN)
- return (ix & 0x7fc00000) == 0x7fc00000;
- return 2 * (ix ^ 0x00400000) > 2u * 0x7fc00000;
-}
-static inline int
-issignaling_d (double x)
-{
- uint64_t ix = asuint64 (x);
- if (!IEEE_754_2008_SNAN)
- return (ix & 0x7ff8000000000000) == 0x7ff8000000000000;
- return 2 * (ix ^ 0x0008000000000000) > 2 * 0x7ff8000000000000ULL;
-}
-
-#if USE_MPFR
-static mpfr_rnd_t
-rmap (int r)
-{
- switch (r)
- {
- case FE_TONEAREST:
- return MPFR_RNDN;
- case FE_TOWARDZERO:
- return MPFR_RNDZ;
- case FE_UPWARD:
- return MPFR_RNDU;
- case FE_DOWNWARD:
- return MPFR_RNDD;
- }
- return -1;
-}
-
-#define prec_mpfr_f 50
-#define prec_mpfr_d 80
-#define prec_f 24
-#define prec_d 53
-#define emin_f -148
-#define emin_d -1073
-#define emax_f 128
-#define emax_d 1024
-static inline int
-call_mpfr_f1 (mpfr_t y, const struct fun *f, struct args_f1 a, mpfr_rnd_t r)
-{
- MPFR_DECL_INIT (x, prec_f);
- mpfr_set_flt (x, a.x, MPFR_RNDN);
- return f->fun_mpfr.f1 (y, x, r);
-}
-static inline int
-call_mpfr_f2 (mpfr_t y, const struct fun *f, struct args_f2 a, mpfr_rnd_t r)
-{
- MPFR_DECL_INIT (x, prec_f);
- MPFR_DECL_INIT (x2, prec_f);
- mpfr_set_flt (x, a.x, MPFR_RNDN);
- mpfr_set_flt (x2, a.x2, MPFR_RNDN);
- return f->fun_mpfr.f2 (y, x, x2, r);
-}
-static inline int
-call_mpfr_d1 (mpfr_t y, const struct fun *f, struct args_d1 a, mpfr_rnd_t r)
-{
- MPFR_DECL_INIT (x, prec_d);
- mpfr_set_d (x, a.x, MPFR_RNDN);
- return f->fun_mpfr.d1 (y, x, r);
-}
-static inline int
-call_mpfr_d2 (mpfr_t y, const struct fun *f, struct args_d2 a, mpfr_rnd_t r)
-{
- MPFR_DECL_INIT (x, prec_d);
- MPFR_DECL_INIT (x2, prec_d);
- mpfr_set_d (x, a.x, MPFR_RNDN);
- mpfr_set_d (x2, a.x2, MPFR_RNDN);
- return f->fun_mpfr.d2 (y, x, x2, r);
-}
-#endif
-
-#define float_f float
-#define double_f double
-#define copysign_f copysignf
-#define nextafter_f nextafterf
-#define fabs_f fabsf
-#define asuint_f asuint
-#define asfloat_f asfloat
-#define scalbn_f scalbnf
-#define lscalbn_f scalbn
-#define halfinf_f 0x1p127f
-#define min_normal_f 0x1p-126f
-
-#define float_d double
-#define double_d long double
-#define copysign_d copysign
-#define nextafter_d nextafter
-#define fabs_d fabs
-#define asuint_d asuint64
-#define asfloat_d asdouble
-#define scalbn_d scalbn
-#define lscalbn_d scalbnl
-#define halfinf_d 0x1p1023
-#define min_normal_d 0x1p-1022
-
-#define NEW_RT
-#define RT(x) x##_f
-#define T(x) x##_f1
-#include "ulp.h"
-#undef T
-#define T(x) x##_f2
-#include "ulp.h"
-#undef T
-#undef RT
-
-#define NEW_RT
-#define RT(x) x##_d
-#define T(x) x##_d1
-#include "ulp.h"
-#undef T
-#define T(x) x##_d2
-#include "ulp.h"
-#undef T
-#undef RT
-
-static void
-usage (void)
-{
- puts ("./ulp [-q] [-m] [-f] [-r nudz] [-l soft-ulplimit] [-e ulplimit] func "
- "lo [hi [x lo2 hi2] [count]]");
- puts ("Compares func against a higher precision implementation in [lo; hi].");
- puts ("-q: quiet.");
- puts ("-m: use mpfr even if faster method is available.");
- puts ("-f: disable fenv testing (rounding modes and exceptions).");
- puts ("Supported func:");
- for (const struct fun *f = fun; f->name; f++)
- printf ("\t%s\n", f->name);
- exit (1);
-}
-
-static void
-cmp (const struct fun *f, struct gen *gen, const struct conf *conf)
-{
- if (f->arity == 1 && f->singleprec)
- cmp_f1 (f, gen, conf);
- else if (f->arity == 2 && f->singleprec)
- cmp_f2 (f, gen, conf);
- else if (f->arity == 1 && !f->singleprec)
- cmp_d1 (f, gen, conf);
- else if (f->arity == 2 && !f->singleprec)
- cmp_d2 (f, gen, conf);
- else
- usage ();
-}
-
-static uint64_t
-getnum (const char *s, int singleprec)
-{
- // int i;
- uint64_t sign = 0;
- // char buf[12];
-
- if (s[0] == '+')
- s++;
- else if (s[0] == '-')
- {
- sign = singleprec ? 1ULL << 31 : 1ULL << 63;
- s++;
- }
- /* 0xXXXX is treated as bit representation, '-' flips the sign bit. */
- if (s[0] == '0' && tolower (s[1]) == 'x' && strchr (s, 'p') == 0)
- return sign ^ strtoull (s, 0, 0);
- // /* SNaN, QNaN, NaN, Inf. */
- // for (i=0; s[i] && i < sizeof buf; i++)
- // buf[i] = tolower(s[i]);
- // buf[i] = 0;
- // if (strcmp(buf, "snan") == 0)
- // return sign | (singleprec ? 0x7fa00000 : 0x7ff4000000000000);
- // if (strcmp(buf, "qnan") == 0 || strcmp(buf, "nan") == 0)
- // return sign | (singleprec ? 0x7fc00000 : 0x7ff8000000000000);
- // if (strcmp(buf, "inf") == 0 || strcmp(buf, "infinity") == 0)
- // return sign | (singleprec ? 0x7f800000 : 0x7ff0000000000000);
- /* Otherwise assume it's a floating-point literal. */
- return sign
- | (singleprec ? asuint (strtof (s, 0)) : asuint64 (strtod (s, 0)));
-}
-
-static void
-parsegen (struct gen *g, int argc, char *argv[], const struct fun *f)
-{
- int singleprec = f->singleprec;
- int arity = f->arity;
- uint64_t a, b, a2, b2, n;
- if (argc < 1)
- usage ();
- b = a = getnum (argv[0], singleprec);
- n = 0;
- if (argc > 1 && strcmp (argv[1], "x") == 0)
- {
- argc -= 2;
- argv += 2;
- }
- else if (argc > 1)
- {
- b = getnum (argv[1], singleprec);
- if (argc > 2 && strcmp (argv[2], "x") == 0)
- {
- argc -= 3;
- argv += 3;
- }
- }
- b2 = a2 = getnum (argv[0], singleprec);
- if (argc > 1)
- b2 = getnum (argv[1], singleprec);
- if (argc > 2)
- n = strtoull (argv[2], 0, 0);
- if (argc > 3)
- usage ();
- //printf("ab %lx %lx ab2 %lx %lx n %lu\n", a, b, a2, b2, n);
- if (arity == 1)
- {
- g->start = a;
- g->len = b - a;
- if (n - 1 > b - a)
- n = b - a + 1;
- g->off = 0;
- g->step = n ? (g->len + 1) / n : 1;
- g->start2 = g->len2 = 0;
- g->cnt = n;
- }
- else if (arity == 2)
- {
- g->start = a;
- g->len = b - a;
- g->off = g->step = 0;
- g->start2 = a2;
- g->len2 = b2 - a2;
- g->cnt = n;
- }
- else
- usage ();
-}
-
-int
-main (int argc, char *argv[])
-{
- const struct fun *f;
- struct gen gen;
- struct conf conf;
- conf.rc = 'n';
- conf.quiet = 0;
- conf.mpfr = 0;
- conf.fenv = 1;
- conf.softlim = 0;
- conf.errlim = INFINITY;
- for (;;)
- {
- argc--;
- argv++;
- if (argc < 1)
- usage ();
- if (argv[0][0] != '-')
- break;
- switch (argv[0][1])
- {
- case 'e':
- argc--;
- argv++;
- if (argc < 1)
- usage ();
- conf.errlim = strtod (argv[0], 0);
- break;
- case 'f':
- conf.fenv = 0;
- break;
- case 'l':
- argc--;
- argv++;
- if (argc < 1)
- usage ();
- conf.softlim = strtod (argv[0], 0);
- break;
- case 'm':
- conf.mpfr = 1;
- break;
- case 'q':
- conf.quiet = 1;
- break;
- case 'r':
- conf.rc = argv[0][2];
- if (!conf.rc)
- {
- argc--;
- argv++;
- if (argc < 1)
- usage ();
- conf.rc = argv[0][0];
- }
- break;
- default:
- usage ();
- }
- }
- switch (conf.rc)
- {
- case 'n':
- conf.r = FE_TONEAREST;
- break;
- case 'u':
- conf.r = FE_UPWARD;
- break;
- case 'd':
- conf.r = FE_DOWNWARD;
- break;
- case 'z':
- conf.r = FE_TOWARDZERO;
- break;
- default:
- usage ();
- }
- for (f = fun; f->name; f++)
- if (strcmp (argv[0], f->name) == 0)
- break;
- if (!f->name)
- usage ();
- if (!f->singleprec && LDBL_MANT_DIG == DBL_MANT_DIG)
- conf.mpfr = 1; /* Use mpfr if long double has no extra precision. */
- if (!USE_MPFR && conf.mpfr)
- {
- puts ("mpfr is not available.");
- return 0;
- }
- argc--;
- argv++;
- parsegen (&gen, argc, argv, f);
- conf.n = gen.cnt;
- cmp (f, &gen, &conf);
-}
diff --git a/math/test/ulp.h b/math/test/ulp.h
deleted file mode 100644
index 07b0cb6..0000000
--- a/math/test/ulp.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Generic functions for ULP error estimation.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* For each different math function type,
- T(x) should add a different suffix to x.
- RT(x) should add a return type specific suffix to x. */
-
-#ifdef NEW_RT
-#undef NEW_RT
-
-# if USE_MPFR
-static int RT(ulpscale_mpfr) (mpfr_t x, int t)
-{
- /* TODO: pow of 2 cases. */
- if (mpfr_regular_p (x))
- {
- mpfr_exp_t e = mpfr_get_exp (x) - RT(prec);
- if (e < RT(emin))
- e = RT(emin) - 1;
- if (e > RT(emax) - RT(prec))
- e = RT(emax) - RT(prec);
- return e;
- }
- if (mpfr_zero_p (x))
- return RT(emin) - 1;
- if (mpfr_inf_p (x))
- return RT(emax) - RT(prec);
- /* NaN. */
- return 0;
-}
-# endif
-
-/* Difference between exact result and closest real number that
- gets rounded to got, i.e. error before rounding, for a correctly
- rounded result the difference is 0. */
-static double RT(ulperr) (RT(float) got, const struct RT(ret) * p, int r)
-{
- RT(float) want = p->y;
- RT(float) d;
- double e;
-
- if (RT(asuint) (got) == RT(asuint) (want))
- return 0.0;
- if (signbit (got) != signbit (want))
- /* May have false positives with NaN. */
- //return isnan(got) && isnan(want) ? 0 : INFINITY;
- return INFINITY;
- if (!isfinite (want) || !isfinite (got))
- {
- if (isnan (got) != isnan (want))
- return INFINITY;
- if (isnan (want))
- return 0;
- if (isinf (got))
- {
- got = RT(copysign) (RT(halfinf), got);
- want *= 0.5f;
- }
- if (isinf (want))
- {
- want = RT(copysign) (RT(halfinf), want);
- got *= 0.5f;
- }
- }
- if (r == FE_TONEAREST)
- {
- // TODO: incorrect when got vs want cross a powof2 boundary
- /* error = got > want
- ? got - want - tail ulp - 0.5 ulp
- : got - want - tail ulp + 0.5 ulp; */
- d = got - want;
- e = d > 0 ? -p->tail - 0.5 : -p->tail + 0.5;
- }
- else
- {
- if ((r == FE_DOWNWARD && got < want) || (r == FE_UPWARD && got > want)
- || (r == FE_TOWARDZERO && fabs (got) < fabs (want)))
- got = RT(nextafter) (got, want);
- d = got - want;
- e = -p->tail;
- }
- return RT(scalbn) (d, -p->ulpexp) + e;
-}
-
-static int RT(isok) (RT(float) ygot, int exgot, RT(float) ywant, int exwant,
- int exmay)
-{
- return RT(asuint) (ygot) == RT(asuint) (ywant)
- && ((exgot ^ exwant) & ~exmay) == 0;
-}
-
-static int RT(isok_nofenv) (RT(float) ygot, RT(float) ywant)
-{
- return RT(asuint) (ygot) == RT(asuint) (ywant);
-}
-#endif
-
-static inline void T(call_fenv) (const struct fun *f, struct T(args) a, int r,
- RT(float) * y, int *ex)
-{
- if (r != FE_TONEAREST)
- fesetround (r);
- feclearexcept (FE_ALL_EXCEPT);
- *y = T(call) (f, a);
- *ex = fetestexcept (FE_ALL_EXCEPT);
- if (r != FE_TONEAREST)
- fesetround (FE_TONEAREST);
-}
-
-static inline void T(call_nofenv) (const struct fun *f, struct T(args) a,
- int r, RT(float) * y, int *ex)
-{
- *y = T(call) (f, a);
- *ex = 0;
-}
-
-static inline int T(call_long_fenv) (const struct fun *f, struct T(args) a,
- int r, struct RT(ret) * p,
- RT(float) ygot, int exgot)
-{
- if (r != FE_TONEAREST)
- fesetround (r);
- feclearexcept (FE_ALL_EXCEPT);
- RT(double) yl = T(call_long) (f, a);
- p->y = (RT(float)) yl;
- volatile RT(float) vy = p->y; // TODO: barrier
- (void) vy;
- p->ex = fetestexcept (FE_ALL_EXCEPT);
- if (r != FE_TONEAREST)
- fesetround (FE_TONEAREST);
- p->ex_may = FE_INEXACT;
- if (RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may))
- return 1;
- p->ulpexp = RT(ulpscale) (p->y);
- if (isinf (p->y))
- p->tail = RT(lscalbn) (yl - (RT(double)) 2 * RT(halfinf), -p->ulpexp);
- else
- p->tail = RT(lscalbn) (yl - p->y, -p->ulpexp);
- if (RT(fabs) (p->y) < RT(min_normal))
- {
- /* TODO: subnormal result is treated as undeflow even if it's
- exact since call_long may not raise inexact correctly. */
- if (p->y != 0 || (p->ex & FE_INEXACT))
- p->ex |= FE_UNDERFLOW | FE_INEXACT;
- }
- return 0;
-}
-static inline int T(call_long_nofenv) (const struct fun *f, struct T(args) a,
- int r, struct RT(ret) * p,
- RT(float) ygot, int exgot)
-{
- RT(double) yl = T(call_long) (f, a);
- p->y = (RT(float)) yl;
- if (RT(isok_nofenv) (ygot, p->y))
- return 1;
- p->ulpexp = RT(ulpscale) (p->y);
- if (isinf (p->y))
- p->tail = RT(lscalbn) (yl - (RT(double)) 2 * RT(halfinf), -p->ulpexp);
- else
- p->tail = RT(lscalbn) (yl - p->y, -p->ulpexp);
- return 0;
-}
-
-/* There are nan input args and all quiet. */
-static inline int T(qnanpropagation) (struct T(args) a)
-{
- return T(reduce) (a, isnan, ||) && !T(reduce) (a, RT(issignaling), ||);
-}
-static inline RT(float) T(sum) (struct T(args) a)
-{
- return T(reduce) (a, , +);
-}
-
-/* returns 1 if the got result is ok. */
-static inline int T(call_mpfr_fix) (const struct fun *f, struct T(args) a,
- int r_fenv, struct RT(ret) * p,
- RT(float) ygot, int exgot)
-{
-#if USE_MPFR
- int t, t2;
- mpfr_rnd_t r = rmap (r_fenv);
- MPFR_DECL_INIT(my, RT(prec_mpfr));
- MPFR_DECL_INIT(mr, RT(prec));
- MPFR_DECL_INIT(me, RT(prec_mpfr));
- mpfr_clear_flags ();
- t = T(call_mpfr) (my, f, a, r);
- /* Double rounding. */
- t2 = mpfr_set (mr, my, r);
- if (t2)
- t = t2;
- mpfr_set_emin (RT(emin));
- mpfr_set_emax (RT(emax));
- t = mpfr_check_range (mr, t, r);
- t = mpfr_subnormalize (mr, t, r);
- mpfr_set_emax (MPFR_EMAX_DEFAULT);
- mpfr_set_emin (MPFR_EMIN_DEFAULT);
- p->y = mpfr_get_d (mr, r);
- p->ex = t ? FE_INEXACT : 0;
- p->ex_may = FE_INEXACT;
- if (mpfr_underflow_p () && (p->ex & FE_INEXACT))
- /* TODO: handle before and after rounding uflow cases. */
- p->ex |= FE_UNDERFLOW;
- if (mpfr_overflow_p ())
- p->ex |= FE_OVERFLOW | FE_INEXACT;
- if (mpfr_divby0_p ())
- p->ex |= FE_DIVBYZERO;
- //if (mpfr_erangeflag_p ())
- // p->ex |= FE_INVALID;
- if (!mpfr_nanflag_p () && RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may))
- return 1;
- if (mpfr_nanflag_p () && !T(qnanpropagation) (a))
- p->ex |= FE_INVALID;
- p->ulpexp = RT(ulpscale_mpfr) (my, t);
- if (!isfinite (p->y))
- {
- p->tail = 0;
- if (isnan (p->y))
- {
- /* If an input was nan keep its sign. */
- p->y = T(sum) (a);
- if (!isnan (p->y))
- p->y = (p->y - p->y) / (p->y - p->y);
- return RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may);
- }
- mpfr_set_si_2exp (mr, signbit (p->y) ? -1 : 1, 1024, MPFR_RNDN);
- if (mpfr_cmpabs (my, mr) >= 0)
- return RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may);
- }
- mpfr_sub (me, my, mr, MPFR_RNDN);
- mpfr_mul_2si (me, me, -p->ulpexp, MPFR_RNDN);
- p->tail = mpfr_get_d (me, MPFR_RNDN);
- return 0;
-#else
- abort ();
-#endif
-}
-
-static void T(cmp) (const struct fun *f, struct gen *gen,
- const struct conf *conf)
-{
- double maxerr = 0;
- uint64_t cnt = 0;
- uint64_t cnt1 = 0;
- uint64_t cnt2 = 0;
- uint64_t cntfail = 0;
- int r = conf->r;
- int use_mpfr = conf->mpfr;
- int fenv = conf->fenv;
- for (;;)
- {
- struct RT(ret) want;
- struct T(args) a = T(next) (gen);
- int exgot;
- RT(float) ygot;
- if (fenv)
- T(call_fenv) (f, a, r, &ygot, &exgot);
- else
- T(call_nofenv) (f, a, r, &ygot, &exgot);
- cnt++;
- int ok = use_mpfr
- ? T(call_mpfr_fix) (f, a, r, &want, ygot, exgot)
- : (fenv ? T(call_long_fenv) (f, a, r, &want, ygot, exgot)
- : T(call_long_nofenv) (f, a, r, &want, ygot, exgot));
- if (!ok)
- {
- int print = 0;
- int fail = 0;
- double err = RT(ulperr) (ygot, &want, r);
- double abserr = fabs (err);
- // TODO: count errors below accuracy limit.
- if (abserr > 0)
- cnt1++;
- if (abserr > 1)
- cnt2++;
- if (abserr > conf->errlim)
- {
- print = fail = 1;
- cntfail++;
- }
- if (abserr > maxerr)
- {
- maxerr = abserr;
- if (!conf->quiet && abserr > conf->softlim)
- print = 1;
- }
- if (print)
- {
- T(printcall) (f, a);
- // TODO: inf ulp handling
- printf (" got %a want %a %+g ulp err %g\n", ygot, want.y,
- want.tail, err);
- }
- int diff = fenv ? exgot ^ want.ex : 0;
- if (fenv && (diff & ~want.ex_may))
- {
- if (!fail)
- {
- fail = 1;
- cntfail++;
- }
- T(printcall) (f, a);
- printf (" is %a %+g ulp, got except 0x%0x", want.y, want.tail,
- exgot);
- if (diff & exgot)
- printf (" wrongly set: 0x%x", diff & exgot);
- if (diff & ~exgot)
- printf (" wrongly clear: 0x%x", diff & ~exgot);
- putchar ('\n');
- }
- }
- if (cnt >= conf->n)
- break;
- if (!conf->quiet && cnt % 0x100000 == 0)
- printf ("progress: %6.3f%% cnt %llu cnt1 %llu cnt2 %llu cntfail %llu "
- "maxerr %g\n",
- 100.0 * cnt / conf->n, (unsigned long long) cnt,
- (unsigned long long) cnt1, (unsigned long long) cnt2,
- (unsigned long long) cntfail, maxerr);
- }
- double cc = cnt;
- if (cntfail)
- printf ("FAIL ");
- else
- printf ("PASS ");
- T(printgen) (f, gen);
- printf (" round %c errlim %g maxerr %g %s cnt %llu cnt1 %llu %g%% cnt2 %llu "
- "%g%% cntfail %llu %g%%\n",
- conf->rc, conf->errlim,
- maxerr, conf->r == FE_TONEAREST ? "+0.5" : "+1.0",
- (unsigned long long) cnt,
- (unsigned long long) cnt1, 100.0 * cnt1 / cc,
- (unsigned long long) cnt2, 100.0 * cnt2 / cc,
- (unsigned long long) cntfail, 100.0 * cntfail / cc);
-}
diff --git a/math/tools/cos.sollya b/math/tools/cos.sollya
deleted file mode 100644
index bd72d6b..0000000
--- a/math/tools/cos.sollya
+++ /dev/null
@@ -1,31 +0,0 @@
-// polynomial for approximating cos(x)
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-deg = 8; // polynomial degree
-a = -pi/4; // interval
-b = pi/4;
-
-// find even polynomial with minimal abs error compared to cos(x)
-
-f = cos(x);
-
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|
-approx = proc(poly,d) {
- return remez(f(x)-poly(x), deg-d, [a;b], x^d, 1e-10);
-};
-
-// first coeff is fixed, iteratively find optimal double prec coeffs
-poly = 1;
-for i from 1 to deg/2 do {
- p = roundcoefficients(approx(poly,2*i), [|D ...|]);
- poly = poly + x^(2*i)*coeff(p,0);
-};
-
-display = hexadecimal;
-print("rel error:", accurateinfnorm(1-poly(x)/f(x), [a;b], 30));
-print("abs error:", accurateinfnorm(f(x)-poly(x), [a;b], 30));
-print("in [",a,b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/math/tools/exp.sollya b/math/tools/exp.sollya
deleted file mode 100644
index b7a462c..0000000
--- a/math/tools/exp.sollya
+++ /dev/null
@@ -1,35 +0,0 @@
-// polynomial for approximating e^x
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-deg = 5; // poly degree
-N = 128; // table entries
-b = log(2)/(2*N); // interval
-b = b + b*0x1p-16; // increase interval for non-nearest rounding (TOINT_NARROW)
-a = -b;
-
-// find polynomial with minimal abs error
-
-// return p that minimizes |exp(x) - poly(x) - x^d*p(x)|
-approx = proc(poly,d) {
- return remez(exp(x)-poly(x), deg-d, [a;b], x^d, 1e-10);
-};
-
-// first 2 coeffs are fixed, iteratively find optimal double prec coeffs
-poly = 1 + x;
-for i from 2 to deg do {
- p = roundcoefficients(approx(poly,i), [|D ...|]);
- poly = poly + x^i*coeff(p,0);
-};
-
-display = hexadecimal;
-print("rel error:", accurateinfnorm(1-poly(x)/exp(x), [a;b], 30));
-print("abs error:", accurateinfnorm(exp(x)-poly(x), [a;b], 30));
-print("in [",a,b,"]");
-// double interval error for non-nearest rounding
-print("rel2 error:", accurateinfnorm(1-poly(x)/exp(x), [2*a;2*b], 30));
-print("abs2 error:", accurateinfnorm(exp(x)-poly(x), [2*a;2*b], 30));
-print("in [",2*a,2*b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/math/tools/exp2.sollya b/math/tools/exp2.sollya
deleted file mode 100644
index e760769..0000000
--- a/math/tools/exp2.sollya
+++ /dev/null
@@ -1,48 +0,0 @@
-// polynomial for approximating 2^x
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-// exp2f parameters
-deg = 3; // poly degree
-N = 32; // table entries
-b = 1/(2*N); // interval
-a = -b;
-
-//// exp2 parameters
-//deg = 5; // poly degree
-//N = 128; // table entries
-//b = 1/(2*N); // interval
-//a = -b;
-
-// find polynomial with minimal relative error
-
-f = 2^x;
-
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|/|f(x)|
-approx = proc(poly,d) {
- return remez(1 - poly(x)/f(x), deg-d, [a;b], x^d/f(x), 1e-10);
-};
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|
-approx_abs = proc(poly,d) {
- return remez(f(x) - poly(x), deg-d, [a;b], x^d, 1e-10);
-};
-
-// first coeff is fixed, iteratively find optimal double prec coeffs
-poly = 1;
-for i from 1 to deg do {
- p = roundcoefficients(approx(poly,i), [|D ...|]);
-// p = roundcoefficients(approx_abs(poly,i), [|D ...|]);
- poly = poly + x^i*coeff(p,0);
-};
-
-display = hexadecimal;
-print("rel error:", accurateinfnorm(1-poly(x)/2^x, [a;b], 30));
-print("abs error:", accurateinfnorm(2^x-poly(x), [a;b], 30));
-print("in [",a,b,"]");
-// double interval error for non-nearest rounding:
-print("rel2 error:", accurateinfnorm(1-poly(x)/2^x, [2*a;2*b], 30));
-print("abs2 error:", accurateinfnorm(2^x-poly(x), [2*a;2*b], 30));
-print("in [",2*a,2*b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/math/tools/log.sollya b/math/tools/log.sollya
deleted file mode 100644
index 6df4db4..0000000
--- a/math/tools/log.sollya
+++ /dev/null
@@ -1,35 +0,0 @@
-// polynomial for approximating log(1+x)
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-deg = 12; // poly degree
-// |log(1+x)| > 0x1p-4 outside the interval
-a = -0x1p-4;
-b = 0x1.09p-4;
-
-// find log(1+x)/x polynomial with minimal relative error
-// (minimal relative error polynomial for log(1+x) is the same * x)
-deg = deg-1; // because of /x
-
-// f = log(1+x)/x; using taylor series
-f = 0;
-for i from 0 to 60 do { f = f + (-x)^i/(i+1); };
-
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|/|f(x)|
-approx = proc(poly,d) {
- return remez(1 - poly(x)/f(x), deg-d, [a;b], x^d/f(x), 1e-10);
-};
-
-// first coeff is fixed, iteratively find optimal double prec coeffs
-poly = 1;
-for i from 1 to deg do {
- p = roundcoefficients(approx(poly,i), [|D ...|]);
- poly = poly + x^i*coeff(p,0);
-};
-
-display = hexadecimal;
-print("rel error:", accurateinfnorm(1-poly(x)/f(x), [a;b], 30));
-print("in [",a,b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/math/tools/log2.sollya b/math/tools/log2.sollya
deleted file mode 100644
index 4a364c0..0000000
--- a/math/tools/log2.sollya
+++ /dev/null
@@ -1,42 +0,0 @@
-// polynomial for approximating log2(1+x)
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-deg = 11; // poly degree
-// |log2(1+x)| > 0x1p-4 outside the interval
-a = -0x1.5b51p-5;
-b = 0x1.6ab2p-5;
-
-ln2 = evaluate(log(2),0);
-invln2hi = double(1/ln2 + 0x1p21) - 0x1p21; // round away last 21 bits
-invln2lo = double(1/ln2 - invln2hi);
-
-// find log2(1+x)/x polynomial with minimal relative error
-// (minimal relative error polynomial for log2(1+x) is the same * x)
-deg = deg-1; // because of /x
-
-// f = log(1+x)/x; using taylor series
-f = 0;
-for i from 0 to 60 do { f = f + (-x)^i/(i+1); };
-f = f/ln2;
-
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|/|f(x)|
-approx = proc(poly,d) {
- return remez(1 - poly(x)/f(x), deg-d, [a;b], x^d/f(x), 1e-10);
-};
-
-// first coeff is fixed, iteratively find optimal double prec coeffs
-poly = invln2hi + invln2lo;
-for i from 1 to deg do {
- p = roundcoefficients(approx(poly,i), [|D ...|]);
- poly = poly + x^i*coeff(p,0);
-};
-
-display = hexadecimal;
-print("invln2hi:", invln2hi);
-print("invln2lo:", invln2lo);
-print("rel error:", accurateinfnorm(1-poly(x)/f(x), [a;b], 30));
-print("in [",a,b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/math/tools/log2_abs.sollya b/math/tools/log2_abs.sollya
deleted file mode 100644
index 82c4dac..0000000
--- a/math/tools/log2_abs.sollya
+++ /dev/null
@@ -1,41 +0,0 @@
-// polynomial for approximating log2(1+x)
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-deg = 7; // poly degree
-// interval ~= 1/(2*N), where N is the table entries
-a= -0x1.f45p-8;
-b= 0x1.f45p-8;
-
-ln2 = evaluate(log(2),0);
-invln2hi = double(1/ln2 + 0x1p21) - 0x1p21; // round away last 21 bits
-invln2lo = double(1/ln2 - invln2hi);
-
-// find log2(1+x) polynomial with minimal absolute error
-f = log(1+x)/ln2;
-
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|
-approx = proc(poly,d) {
- return remez(f(x) - poly(x), deg-d, [a;b], x^d, 1e-10);
-};
-
-// first coeff is fixed, iteratively find optimal double prec coeffs
-poly = x*(invln2lo + invln2hi);
-for i from 2 to deg do {
- p = roundcoefficients(approx(poly,i), [|D ...|]);
- poly = poly + x^i*coeff(p,0);
-};
-
-display = hexadecimal;
-print("invln2hi:", invln2hi);
-print("invln2lo:", invln2lo);
-print("abs error:", accurateinfnorm(f(x)-poly(x), [a;b], 30));
-//// relative error computation fails if f(0)==0
-//// g = f(x)/x = log2(1+x)/x; using taylor series
-//g = 0;
-//for i from 0 to 60 do { g = g + (-x)^i/(i+1)/ln2; };
-//print("rel error:", accurateinfnorm(1-(poly(x)/x)/g(x), [a;b], 30));
-print("in [",a,b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/math/tools/log_abs.sollya b/math/tools/log_abs.sollya
deleted file mode 100644
index a2ac190..0000000
--- a/math/tools/log_abs.sollya
+++ /dev/null
@@ -1,35 +0,0 @@
-// polynomial for approximating log(1+x)
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-deg = 6; // poly degree
-// interval ~= 1/(2*N), where N is the table entries
-a = -0x1.fp-9;
-b = 0x1.fp-9;
-
-// find log(1+x) polynomial with minimal absolute error
-f = log(1+x);
-
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|
-approx = proc(poly,d) {
- return remez(f(x) - poly(x), deg-d, [a;b], x^d, 1e-10);
-};
-
-// first coeff is fixed, iteratively find optimal double prec coeffs
-poly = x;
-for i from 2 to deg do {
- p = roundcoefficients(approx(poly,i), [|D ...|]);
- poly = poly + x^i*coeff(p,0);
-};
-
-display = hexadecimal;
-print("abs error:", accurateinfnorm(f(x)-poly(x), [a;b], 30));
-// relative error computation fails if f(0)==0
-// g = f(x)/x = log(1+x)/x; using taylor series
-g = 0;
-for i from 0 to 60 do { g = g + (-x)^i/(i+1); };
-print("rel error:", accurateinfnorm(1-poly(x)/x/g(x), [a;b], 30));
-print("in [",a,b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/math/tools/plot.py b/math/tools/plot.py
deleted file mode 100755
index 09c8ec6..0000000
--- a/math/tools/plot.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/python
-
-# ULP error plot tool.
-#
-# Copyright (c) 2019, Arm Limited.
-# SPDX-License-Identifier: MIT
-
-import numpy as np
-import matplotlib.pyplot as plt
-import sys
-import re
-
-# example usage:
-# build/bin/ulp -e .0001 log 0.5 2.0 2345678 | math/tools/plot.py
-
-def fhex(s):
- return float.fromhex(s)
-
-def parse(f):
- xs = []
- ys = []
- es = []
- # Has to match the format used in ulp.c
- r = re.compile(r'[^ (]+\(([^ )]*)\) got [^ ]+ want ([^ ]+) [^ ]+ ulp err ([^ ]+)')
- for line in f:
- m = r.match(line)
- if m:
- x = fhex(m.group(1))
- y = fhex(m.group(2))
- e = float(m.group(3))
- xs.append(x)
- ys.append(y)
- es.append(e)
- elif line.startswith('PASS') or line.startswith('FAIL'):
- # Print the summary line
- print(line)
- return xs, ys, es
-
-def plot(xs, ys, es):
- if len(xs) < 2:
- print('not enough samples')
- return
- a = min(xs)
- b = max(xs)
- fig, (ax0,ax1) = plt.subplots(nrows=2)
- es = map(abs, es) # ignore the sign
- emax = max(es)
- ax0.text(a+(b-a)*0.7, emax*0.8, '%s\n%g'%(emax.hex(),emax))
- ax0.plot(xs,es,'rx')
- ax0.grid()
- ax1.plot(xs,ys,'rx')
- ax1.grid()
- plt.show()
-
-xs, ys, es = parse(sys.stdin)
-plot(xs, ys, es)
diff --git a/math/tools/sin.sollya b/math/tools/sin.sollya
deleted file mode 100644
index a6e8511..0000000
--- a/math/tools/sin.sollya
+++ /dev/null
@@ -1,37 +0,0 @@
-// polynomial for approximating sin(x)
-//
-// Copyright (c) 2019, Arm Limited.
-// SPDX-License-Identifier: MIT
-
-deg = 7; // polynomial degree
-a = -pi/4; // interval
-b = pi/4;
-
-// find even polynomial with minimal abs error compared to sin(x)/x
-
-// account for /x
-deg = deg-1;
-
-// f = sin(x)/x;
-f = 1;
-c = 1;
-for i from 1 to 60 do { c = 2*i*(2*i + 1)*c; f = f + (-1)^i*x^(2*i)/c; };
-
-// return p that minimizes |f(x) - poly(x) - x^d*p(x)|
-approx = proc(poly,d) {
- return remez(f(x)-poly(x), deg-d, [a;b], x^d, 1e-10);
-};
-
-// first coeff is fixed, iteratively find optimal double prec coeffs
-poly = 1;
-for i from 1 to deg/2 do {
- p = roundcoefficients(approx(poly,2*i), [|D ...|]);
- poly = poly + x^(2*i)*coeff(p,0);
-};
-
-display = hexadecimal;
-print("rel error:", accurateinfnorm(1-poly(x)/f(x), [a;b], 30));
-print("abs error:", accurateinfnorm(sin(x)-x*poly(x), [a;b], 30));
-print("in [",a,b,"]");
-print("coeffs:");
-for i from 0 to deg do coeff(poly,i);
diff --git a/string/Dir.mk b/string/Dir.mk
deleted file mode 100644
index bd9979f..0000000
--- a/string/Dir.mk
+++ /dev/null
@@ -1,75 +0,0 @@
-# Makefile fragment - requires GNU make
-#
-# Copyright (c) 2019, Arm Limited.
-# SPDX-License-Identifier: MIT
-
-string-lib-srcs := $(wildcard $(srcdir)/string/*.[cS])
-string-includes-src := $(wildcard $(srcdir)/string/include/*.h)
-string-includes := $(string-includes-src:$(srcdir)/string/%=build/%)
-string-test-srcs := $(wildcard $(srcdir)/string/test/*.c)
-
-string-libs := \
- build/lib/libstringlib.so \
- build/lib/libstringlib.a \
-
-string-tools := \
- build/bin/test/memcpy \
- build/bin/test/memmove \
- build/bin/test/memset \
- build/bin/test/memchr \
- build/bin/test/memcmp \
- build/bin/test/strcpy \
- build/bin/test/strcmp \
- build/bin/test/strchr \
- build/bin/test/strrchr \
- build/bin/test/strchrnul \
- build/bin/test/strlen \
- build/bin/test/strnlen \
- build/bin/test/strncmp
-
-string-lib-base := $(basename $(string-lib-srcs))
-string-lib-objs := $(string-lib-base:$(srcdir)/%=build/%.o)
-string-test-base := $(basename $(string-test-srcs))
-string-test-objs := $(string-test-base:$(srcdir)/%=build/%.o)
-
-string-objs := \
- $(string-lib-objs) \
- $(string-test-objs) \
-
-all-string: $(string-libs) $(string-tools) $(string-includes)
-
-$(string-objs) $(string-objs:%.o=%.os): $(string-includes)
-
-build/lib/libstringlib.so: $(string-lib-objs:%.o=%.os)
- $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -shared -o $@ $^
-
-build/lib/libstringlib.a: $(string-lib-objs)
- rm -f $@
- $(AR) rc $@ $^
- $(RANLIB) $@
-
-build/bin/test/%: build/string/test/%.o build/lib/libstringlib.a
- $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -static -o $@ $^ $(LDLIBS)
-
-build/include/%.h: $(srcdir)/string/include/%.h
- cp $< $@
-
-build/bin/%.sh: $(srcdir)/string/test/%.sh
- cp $< $@
-
-check-string: $(string-tools)
- $(EMULATOR) build/bin/test/memcpy
- $(EMULATOR) build/bin/test/memmove
- $(EMULATOR) build/bin/test/memset
- $(EMULATOR) build/bin/test/memchr
- $(EMULATOR) build/bin/test/memcmp
- $(EMULATOR) build/bin/test/strcpy
- $(EMULATOR) build/bin/test/strcmp
- $(EMULATOR) build/bin/test/strchr
- $(EMULATOR) build/bin/test/strrchr
- $(EMULATOR) build/bin/test/strchrnul
- $(EMULATOR) build/bin/test/strlen
- $(EMULATOR) build/bin/test/strnlen
- $(EMULATOR) build/bin/test/strncmp
-
-.PHONY: all-string check-string
diff --git a/string/aarch64/memchr-sve.S b/string/aarch64/memchr-sve.S
deleted file mode 100644
index 0d75acd..0000000
--- a/string/aarch64/memchr-sve.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * memchr - find a character in a memory zone
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
- .globl __memchr_aarch64_sve
- .type __memchr_aarch64_sve, %function
- .p2align 4
-__memchr_aarch64_sve:
- dup z1.b, w1 /* duplicate c to a vector */
- setffr /* initialize FFR */
- mov x3, 0 /* initialize off */
- nop
-
-0: whilelo p1.b, x3, x2 /* make sure off < max */
- b.none 9f
-
- /* Read a vector's worth of bytes, bounded by max,
- stopping on first fault. */
- ldff1b z0.b, p1/z, [x0, x3]
- rdffrs p0.b, p1/z
- b.nlast 2f
-
- /* First fault did not fail: the vector bounded by max is valid.
- Avoid depending on the contents of FFR beyond the branch. */
- incb x3 /* speculate increment */
- cmpeq p2.b, p1/z, z0.b, z1.b /* search for c */
- b.none 0b
- decb x3 /* undo speculate */
-
- /* Found C. */
-1: brkb p2.b, p1/z, p2.b /* find the first c */
- add x0, x0, x3 /* form partial pointer */
- incp x0, p2.b /* form final pointer to c */
- ret
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparision only on the valid bytes. */
-2: cmpeq p2.b, p0/z, z0.b, z1.b
- b.any 1b
-
- /* No C found. Re-init FFR, increment, and loop. */
- setffr
- incp x3, p0.b
- b 0b
-
- /* Found end of count. */
-9: mov x0, 0 /* return null */
- ret
-
- .size __memchr_aarch64_sve, . - __memchr_aarch64_sve
diff --git a/string/aarch64/memchr.S b/string/aarch64/memchr.S
deleted file mode 100644
index e5a3abf..0000000
--- a/string/aarch64/memchr.S
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * memchr - find a character in a memory zone
- *
- * Copyright (c) 2014-2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Neon Available.
- */
-
-/* Arguments and results. */
-#define srcin x0
-#define chrin w1
-#define cntin x2
-
-#define result x0
-
-#define src x3
-#define tmp x4
-#define wtmp2 w5
-#define synd x6
-#define soff x9
-#define cntrem x10
-
-#define vrepchr v0
-#define vdata1 v1
-#define vdata2 v2
-#define vhas_chr1 v3
-#define vhas_chr2 v4
-#define vrepmask v5
-#define vend v6
-
-/*
- * Core algorithm:
- *
- * For each 32-byte chunk we calculate a 64-bit syndrome value, with two bits
- * per byte. For each tuple, bit 0 is set if the relevant byte matched the
- * requested character and bit 1 is not used (faster than using a 32bit
- * syndrome). Since the bits in the syndrome reflect exactly the order in which
- * things occur in the original string, counting trailing zeros allows to
- * identify exactly which byte has matched.
- */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-def_fn __memchr_aarch64
- /* Do not dereference srcin if no bytes to compare. */
- cbz cntin, .Lzero_length
- /*
- * Magic constant 0x40100401 allows us to identify which lane matches
- * the requested byte.
- */
- mov wtmp2, #0x0401
- movk wtmp2, #0x4010, lsl #16
- dup vrepchr.16b, chrin
- /* Work with aligned 32-byte chunks */
- bic src, srcin, #31
- dup vrepmask.4s, wtmp2
- ands soff, srcin, #31
- and cntrem, cntin, #31
- b.eq .Lloop
-
- /*
- * Input string is not 32-byte aligned. We calculate the syndrome
- * value for the aligned 32 bytes block containing the first bytes
- * and mask the irrelevant part.
- */
-
- ld1 {vdata1.16b, vdata2.16b}, [src], #32
- sub tmp, soff, #32
- adds cntin, cntin, tmp
- cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
- cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
- and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
- and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
- addp vend.16b, vhas_chr1.16b, vhas_chr2.16b /* 256->128 */
- addp vend.16b, vend.16b, vend.16b /* 128->64 */
- mov synd, vend.2d[0]
- /* Clear the soff*2 lower bits */
- lsl tmp, soff, #1
- lsr synd, synd, tmp
- lsl synd, synd, tmp
- /* The first block can also be the last */
- b.ls .Lmasklast
- /* Have we found something already? */
- cbnz synd, .Ltail
-
-.Lloop:
- ld1 {vdata1.16b, vdata2.16b}, [src], #32
- subs cntin, cntin, #32
- cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
- cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
- /* If we're out of data we finish regardless of the result */
- b.ls .Lend
- /* Use a fast check for the termination condition */
- orr vend.16b, vhas_chr1.16b, vhas_chr2.16b
- addp vend.2d, vend.2d, vend.2d
- mov synd, vend.2d[0]
- /* We're not out of data, loop if we haven't found the character */
- cbz synd, .Lloop
-
-.Lend:
- /* Termination condition found, let's calculate the syndrome value */
- and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
- and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
- addp vend.16b, vhas_chr1.16b, vhas_chr2.16b /* 256->128 */
- addp vend.16b, vend.16b, vend.16b /* 128->64 */
- mov synd, vend.2d[0]
- /* Only do the clear for the last possible block */
- b.hi .Ltail
-
-.Lmasklast:
- /* Clear the (32 - ((cntrem + soff) % 32)) * 2 upper bits */
- add tmp, cntrem, soff
- and tmp, tmp, #31
- sub tmp, tmp, #32
- neg tmp, tmp, lsl #1
- lsl synd, synd, tmp
- lsr synd, synd, tmp
-
-.Ltail:
- /* Count the trailing zeros using bit reversing */
- rbit synd, synd
- /* Compensate the last post-increment */
- sub src, src, #32
- /* Check that we have found a character */
- cmp synd, #0
- /* And count the leading zeros */
- clz synd, synd
- /* Compute the potential result */
- add result, src, synd, lsr #1
- /* Select result or NULL */
- csel result, xzr, result, eq
- ret
-
-.Lzero_length:
- mov result, #0
- ret
-
- .size __memchr_aarch64, . - __memchr_aarch64
diff --git a/string/aarch64/memcmp-sve.S b/string/aarch64/memcmp-sve.S
deleted file mode 100644
index d4f6026..0000000
--- a/string/aarch64/memcmp-sve.S
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * memcmp - compare memory
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
- .globl __memcmp_aarch64_sve
- .type __memcmp_aarch64_sve, %function
- .p2align 4
-__memcmp_aarch64_sve:
- mov x3, 0 /* initialize off */
-
-0: whilelo p0.b, x3, x2 /* while off < max */
- b.none 9f
-
- ld1b z0.b, p0/z, [x0, x3] /* read vectors bounded by max. */
- ld1b z1.b, p0/z, [x1, x3]
-
- /* Increment for a whole vector, even if we've only read a partial.
- This is significantly cheaper than INCP, and since OFF is not
- used after the loop it is ok to increment OFF past MAX. */
- incb x3
-
- cmpne p1.b, p0/z, z0.b, z1.b /* while no inequalities */
- b.none 0b
-
- /* Found inequality. */
-1: brkb p1.b, p0/z, p1.b /* find first such */
- lasta w0, p1, z0.b /* extract each byte */
- lasta w1, p1, z1.b
- sub x0, x0, x1 /* return comparison */
- ret
-
- /* Found end-of-count. */
-9: mov x0, 0 /* return equality */
- ret
-
- .size __memcmp_aarch64_sve, . - __memcmp_aarch64_sve
diff --git a/string/aarch64/memcmp.S b/string/aarch64/memcmp.S
deleted file mode 100644
index 72a66bc..0000000
--- a/string/aarch64/memcmp.S
+++ /dev/null
@@ -1,141 +0,0 @@
-/* memcmp - compare memory
- *
- * Copyright (c) 2013, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses.
- */
-
-#define L(l) .L ## l
-
-/* Parameters and result. */
-#define src1 x0
-#define src2 x1
-#define limit x2
-#define result w0
-
-/* Internal variables. */
-#define data1 x3
-#define data1w w3
-#define data1h x4
-#define data2 x5
-#define data2w w5
-#define data2h x6
-#define tmp1 x7
-#define tmp2 x8
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-def_fn __memcmp_aarch64 p2align=6
- subs limit, limit, 8
- b.lo L(less8)
-
- ldr data1, [src1], 8
- ldr data2, [src2], 8
- cmp data1, data2
- b.ne L(return)
-
- subs limit, limit, 8
- b.gt L(more16)
-
- ldr data1, [src1, limit]
- ldr data2, [src2, limit]
- b L(return)
-
-L(more16):
- ldr data1, [src1], 8
- ldr data2, [src2], 8
- cmp data1, data2
- bne L(return)
-
- /* Jump directly to comparing the last 16 bytes for 32 byte (or less)
- strings. */
- subs limit, limit, 16
- b.ls L(last_bytes)
-
- /* We overlap loads between 0-32 bytes at either side of SRC1 when we
- try to align, so limit it only to strings larger than 128 bytes. */
- cmp limit, 96
- b.ls L(loop16)
-
- /* Align src1 and adjust src2 with bytes not yet done. */
- and tmp1, src1, 15
- add limit, limit, tmp1
- sub src1, src1, tmp1
- sub src2, src2, tmp1
-
- /* Loop performing 16 bytes per iteration using aligned src1.
- Limit is pre-decremented by 16 and must be larger than zero.
- Exit if <= 16 bytes left to do or if the data is not equal. */
- .p2align 4
-L(loop16):
- ldp data1, data1h, [src1], 16
- ldp data2, data2h, [src2], 16
- subs limit, limit, 16
- ccmp data1, data2, 0, hi
- ccmp data1h, data2h, 0, eq
- b.eq L(loop16)
-
- cmp data1, data2
- bne L(return)
- mov data1, data1h
- mov data2, data2h
- cmp data1, data2
- bne L(return)
-
- /* Compare last 1-16 bytes using unaligned access. */
-L(last_bytes):
- add src1, src1, limit
- add src2, src2, limit
- ldp data1, data1h, [src1]
- ldp data2, data2h, [src2]
- cmp data1, data2
- bne L(return)
- mov data1, data1h
- mov data2, data2h
- cmp data1, data2
-
- /* Compare data bytes and set return value to 0, -1 or 1. */
-L(return):
-#ifndef __AARCH64EB__
- rev data1, data1
- rev data2, data2
-#endif
- cmp data1, data2
-L(ret_eq):
- cset result, ne
- cneg result, result, lo
- ret
-
- .p2align 4
- /* Compare up to 8 bytes. Limit is [-8..-1]. */
-L(less8):
- adds limit, limit, 4
- b.lo L(less4)
- ldr data1w, [src1], 4
- ldr data2w, [src2], 4
- cmp data1w, data2w
- b.ne L(return)
- sub limit, limit, 4
-L(less4):
- adds limit, limit, 4
- beq L(ret_eq)
-L(byte_loop):
- ldrb data1w, [src1], 1
- ldrb data2w, [src2], 1
- subs limit, limit, 1
- ccmp data1w, data2w, 0, ne /* NZCV = 0b0000. */
- b.eq L(byte_loop)
- sub result, data1w, data2w
- ret
-
- .size __memcmp_aarch64, . - __memcmp_aarch64
diff --git a/string/aarch64/memcpy.S b/string/aarch64/memcpy.S
deleted file mode 100644
index 4bbd288..0000000
--- a/string/aarch64/memcpy.S
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * memcpy - copy memory area
- *
- * Copyright (c) 2012, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses.
- *
- */
-
-#define dstin x0
-#define src x1
-#define count x2
-#define dst x3
-#define srcend x4
-#define dstend x5
-#define A_l x6
-#define A_lw w6
-#define A_h x7
-#define A_hw w7
-#define B_l x8
-#define B_lw w8
-#define B_h x9
-#define C_l x10
-#define C_h x11
-#define D_l x12
-#define D_h x13
-#define E_l src
-#define E_h count
-#define F_l srcend
-#define F_h dst
-#define tmp1 x9
-
-#define L(l) .L ## l
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-/* Copies are split into 3 main cases: small copies of up to 16 bytes,
- medium copies of 17..96 bytes which are fully unrolled. Large copies
- of more than 96 bytes align the destination and use an unrolled loop
- processing 64 bytes per iteration.
- Small and medium copies read all data before writing, allowing any
- kind of overlap, and memmove tailcalls memcpy for these cases as
- well as non-overlapping copies.
-*/
-
-def_fn __memcpy_aarch64 p2align=6
- prfm PLDL1KEEP, [src]
- add srcend, src, count
- add dstend, dstin, count
- cmp count, 16
- b.ls L(copy16)
- cmp count, 96
- b.hi L(copy_long)
-
- /* Medium copies: 17..96 bytes. */
- sub tmp1, count, 1
- ldp A_l, A_h, [src]
- tbnz tmp1, 6, L(copy96)
- ldp D_l, D_h, [srcend, -16]
- tbz tmp1, 5, 1f
- ldp B_l, B_h, [src, 16]
- ldp C_l, C_h, [srcend, -32]
- stp B_l, B_h, [dstin, 16]
- stp C_l, C_h, [dstend, -32]
-1:
- stp A_l, A_h, [dstin]
- stp D_l, D_h, [dstend, -16]
- ret
-
- .p2align 4
- /* Small copies: 0..16 bytes. */
-L(copy16):
- cmp count, 8
- b.lo 1f
- ldr A_l, [src]
- ldr A_h, [srcend, -8]
- str A_l, [dstin]
- str A_h, [dstend, -8]
- ret
- .p2align 4
-1:
- tbz count, 2, 1f
- ldr A_lw, [src]
- ldr A_hw, [srcend, -4]
- str A_lw, [dstin]
- str A_hw, [dstend, -4]
- ret
-
- /* Copy 0..3 bytes. Use a branchless sequence that copies the same
- byte 3 times if count==1, or the 2nd byte twice if count==2. */
-1:
- cbz count, 2f
- lsr tmp1, count, 1
- ldrb A_lw, [src]
- ldrb A_hw, [srcend, -1]
- ldrb B_lw, [src, tmp1]
- strb A_lw, [dstin]
- strb B_lw, [dstin, tmp1]
- strb A_hw, [dstend, -1]
-2: ret
-
- .p2align 4
- /* Copy 64..96 bytes. Copy 64 bytes from the start and
- 32 bytes from the end. */
-L(copy96):
- ldp B_l, B_h, [src, 16]
- ldp C_l, C_h, [src, 32]
- ldp D_l, D_h, [src, 48]
- ldp E_l, E_h, [srcend, -32]
- ldp F_l, F_h, [srcend, -16]
- stp A_l, A_h, [dstin]
- stp B_l, B_h, [dstin, 16]
- stp C_l, C_h, [dstin, 32]
- stp D_l, D_h, [dstin, 48]
- stp E_l, E_h, [dstend, -32]
- stp F_l, F_h, [dstend, -16]
- ret
-
- /* Align DST to 16 byte alignment so that we don't cross cache line
- boundaries on both loads and stores. There are at least 96 bytes
- to copy, so copy 16 bytes unaligned and then align. The loop
- copies 64 bytes per iteration and prefetches one iteration ahead. */
-
- .p2align 4
-L(copy_long):
- and tmp1, dstin, 15
- bic dst, dstin, 15
- ldp D_l, D_h, [src]
- sub src, src, tmp1
- add count, count, tmp1 /* Count is now 16 too large. */
- ldp A_l, A_h, [src, 16]
- stp D_l, D_h, [dstin]
- ldp B_l, B_h, [src, 32]
- ldp C_l, C_h, [src, 48]
- ldp D_l, D_h, [src, 64]!
- subs count, count, 128 + 16 /* Test and readjust count. */
- b.ls 2f
-1:
- stp A_l, A_h, [dst, 16]
- ldp A_l, A_h, [src, 16]
- stp B_l, B_h, [dst, 32]
- ldp B_l, B_h, [src, 32]
- stp C_l, C_h, [dst, 48]
- ldp C_l, C_h, [src, 48]
- stp D_l, D_h, [dst, 64]!
- ldp D_l, D_h, [src, 64]!
- subs count, count, 64
- b.hi 1b
-
- /* Write the last full set of 64 bytes. The remainder is at most 64
- bytes, so it is safe to always copy 64 bytes from the end even if
- there is just 1 byte left. */
-2:
- ldp E_l, E_h, [srcend, -64]
- stp A_l, A_h, [dst, 16]
- ldp A_l, A_h, [srcend, -48]
- stp B_l, B_h, [dst, 32]
- ldp B_l, B_h, [srcend, -32]
- stp C_l, C_h, [dst, 48]
- ldp C_l, C_h, [srcend, -16]
- stp D_l, D_h, [dst, 64]
- stp E_l, E_h, [dstend, -64]
- stp A_l, A_h, [dstend, -48]
- stp B_l, B_h, [dstend, -32]
- stp C_l, C_h, [dstend, -16]
- ret
-
- .size __memcpy_aarch64, . - __memcpy_aarch64
diff --git a/string/aarch64/memmove.S b/string/aarch64/memmove.S
deleted file mode 100644
index 5e70f21..0000000
--- a/string/aarch64/memmove.S
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * memmove - copy memory area
- *
- * Copyright (c) 2013, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses
- */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-/* Parameters and result. */
-#define dstin x0
-#define src x1
-#define count x2
-#define srcend x3
-#define dstend x4
-#define tmp1 x5
-#define A_l x6
-#define A_h x7
-#define B_l x8
-#define B_h x9
-#define C_l x10
-#define C_h x11
-#define D_l x12
-#define D_h x13
-#define E_l count
-#define E_h tmp1
-
-/* All memmoves up to 96 bytes are done by memcpy as it supports overlaps.
- Larger backwards copies are also handled by memcpy. The only remaining
- case is forward large copies. The destination is aligned, and an
- unrolled loop processes 64 bytes per iteration.
-*/
-
-def_fn __memmove_aarch64, 6
- sub tmp1, dstin, src
- cmp count, 96
- ccmp tmp1, count, 2, hi
- b.hs __memcpy_aarch64
-
- cbz tmp1, 3f
- add dstend, dstin, count
- add srcend, src, count
-
- /* Align dstend to 16 byte alignment so that we don't cross cache line
- boundaries on both loads and stores. There are at least 96 bytes
- to copy, so copy 16 bytes unaligned and then align. The loop
- copies 64 bytes per iteration and prefetches one iteration ahead. */
-
- and tmp1, dstend, 15
- ldp D_l, D_h, [srcend, -16]
- sub srcend, srcend, tmp1
- sub count, count, tmp1
- ldp A_l, A_h, [srcend, -16]
- stp D_l, D_h, [dstend, -16]
- ldp B_l, B_h, [srcend, -32]
- ldp C_l, C_h, [srcend, -48]
- ldp D_l, D_h, [srcend, -64]!
- sub dstend, dstend, tmp1
- subs count, count, 128
- b.ls 2f
- nop
-1:
- stp A_l, A_h, [dstend, -16]
- ldp A_l, A_h, [srcend, -16]
- stp B_l, B_h, [dstend, -32]
- ldp B_l, B_h, [srcend, -32]
- stp C_l, C_h, [dstend, -48]
- ldp C_l, C_h, [srcend, -48]
- stp D_l, D_h, [dstend, -64]!
- ldp D_l, D_h, [srcend, -64]!
- subs count, count, 64
- b.hi 1b
-
- /* Write the last full set of 64 bytes. The remainder is at most 64
- bytes, so it is safe to always copy 64 bytes from the start even if
- there is just 1 byte left. */
-2:
- ldp E_l, E_h, [src, 48]
- stp A_l, A_h, [dstend, -16]
- ldp A_l, A_h, [src, 32]
- stp B_l, B_h, [dstend, -32]
- ldp B_l, B_h, [src, 16]
- stp C_l, C_h, [dstend, -48]
- ldp C_l, C_h, [src]
- stp D_l, D_h, [dstend, -64]
- stp E_l, E_h, [dstin, 48]
- stp A_l, A_h, [dstin, 32]
- stp B_l, B_h, [dstin, 16]
- stp C_l, C_h, [dstin]
-3: ret
-
- .size __memmove_aarch64, . - __memmove_aarch64
diff --git a/string/aarch64/memset.S b/string/aarch64/memset.S
deleted file mode 100644
index aef22e9..0000000
--- a/string/aarch64/memset.S
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * memset - fill memory with a constant byte
- *
- * Copyright (c) 2012, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses
- *
- */
-
-
-#define dstin x0
-#define val x1
-#define valw w1
-#define count x2
-#define dst x3
-#define dstend x4
-#define tmp1 x5
-#define tmp1w w5
-#define tmp2 x6
-#define tmp2w w6
-#define zva_len x7
-#define zva_lenw w7
-
-#define L(l) .L ## l
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-def_fn __memset_aarch64 p2align=6
-
- dup v0.16B, valw
- add dstend, dstin, count
-
- cmp count, 96
- b.hi L(set_long)
- cmp count, 16
- b.hs L(set_medium)
- mov val, v0.D[0]
-
- /* Set 0..15 bytes. */
- tbz count, 3, 1f
- str val, [dstin]
- str val, [dstend, -8]
- ret
- nop
-1: tbz count, 2, 2f
- str valw, [dstin]
- str valw, [dstend, -4]
- ret
-2: cbz count, 3f
- strb valw, [dstin]
- tbz count, 1, 3f
- strh valw, [dstend, -2]
-3: ret
-
- /* Set 17..96 bytes. */
-L(set_medium):
- str q0, [dstin]
- tbnz count, 6, L(set96)
- str q0, [dstend, -16]
- tbz count, 5, 1f
- str q0, [dstin, 16]
- str q0, [dstend, -32]
-1: ret
-
- .p2align 4
- /* Set 64..96 bytes. Write 64 bytes from the start and
- 32 bytes from the end. */
-L(set96):
- str q0, [dstin, 16]
- stp q0, q0, [dstin, 32]
- stp q0, q0, [dstend, -32]
- ret
-
- .p2align 3
- nop
-L(set_long):
- and valw, valw, 255
- bic dst, dstin, 15
- str q0, [dstin]
- cmp count, 256
- ccmp valw, 0, 0, cs
- b.eq L(try_zva)
-L(no_zva):
- sub count, dstend, dst /* Count is 16 too large. */
- add dst, dst, 16
- sub count, count, 64 + 16 /* Adjust count and bias for loop. */
-1: stp q0, q0, [dst], 64
- stp q0, q0, [dst, -32]
-L(tail64):
- subs count, count, 64
- b.hi 1b
-2: stp q0, q0, [dstend, -64]
- stp q0, q0, [dstend, -32]
- ret
-
- .p2align 3
-L(try_zva):
- mrs tmp1, dczid_el0
- tbnz tmp1w, 4, L(no_zva)
- and tmp1w, tmp1w, 15
- cmp tmp1w, 4 /* ZVA size is 64 bytes. */
- b.ne L(zva_128)
-
- /* Write the first and last 64 byte aligned block using stp rather
- than using DC ZVA. This is faster on some cores.
- */
-L(zva_64):
- str q0, [dst, 16]
- stp q0, q0, [dst, 32]
- bic dst, dst, 63
- stp q0, q0, [dst, 64]
- stp q0, q0, [dst, 96]
- sub count, dstend, dst /* Count is now 128 too large. */
- sub count, count, 128+64+64 /* Adjust count and bias for loop. */
- add dst, dst, 128
- nop
-1: dc zva, dst
- add dst, dst, 64
- subs count, count, 64
- b.hi 1b
- stp q0, q0, [dst, 0]
- stp q0, q0, [dst, 32]
- stp q0, q0, [dstend, -64]
- stp q0, q0, [dstend, -32]
- ret
-
- .p2align 3
-L(zva_128):
- cmp tmp1w, 5 /* ZVA size is 128 bytes. */
- b.ne L(zva_other)
-
- str q0, [dst, 16]
- stp q0, q0, [dst, 32]
- stp q0, q0, [dst, 64]
- stp q0, q0, [dst, 96]
- bic dst, dst, 127
- sub count, dstend, dst /* Count is now 128 too large. */
- sub count, count, 128+128 /* Adjust count and bias for loop. */
- add dst, dst, 128
-1: dc zva, dst
- add dst, dst, 128
- subs count, count, 128
- b.hi 1b
- stp q0, q0, [dstend, -128]
- stp q0, q0, [dstend, -96]
- stp q0, q0, [dstend, -64]
- stp q0, q0, [dstend, -32]
- ret
-
-L(zva_other):
- mov tmp2w, 4
- lsl zva_lenw, tmp2w, tmp1w
- add tmp1, zva_len, 64 /* Max alignment bytes written. */
- cmp count, tmp1
- blo L(no_zva)
-
- sub tmp2, zva_len, 1
- add tmp1, dst, zva_len
- add dst, dst, 16
- subs count, tmp1, dst /* Actual alignment bytes to write. */
- bic tmp1, tmp1, tmp2 /* Aligned dc zva start address. */
- beq 2f
-1: stp q0, q0, [dst], 64
- stp q0, q0, [dst, -32]
- subs count, count, 64
- b.hi 1b
-2: mov dst, tmp1
- sub count, dstend, tmp1 /* Remaining bytes to write. */
- subs count, count, zva_len
- b.lo 4f
-3: dc zva, dst
- add dst, dst, zva_len
- subs count, count, zva_len
- b.hs 3b
-4: add count, count, zva_len
- b L(tail64)
-
- .size __memset_aarch64, . - __memset_aarch64
diff --git a/string/aarch64/strchr-sve.S b/string/aarch64/strchr-sve.S
deleted file mode 100644
index 8d8a319..0000000
--- a/string/aarch64/strchr-sve.S
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * strchr/strchrnul - find a character in a string
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
-/* To build as strchrnul, define BUILD_STRCHRNUL before compiling this file. */
-#ifdef BUILD_STRCHRNUL
-#define FUNC __strchrnul_aarch64_sve
-#else
-#define FUNC __strchr_aarch64_sve
-#endif
-
- .globl FUNC
- .type FUNC, %function
- .p2align 4
-FUNC:
- dup z1.b, w1 /* replicate byte across vector */
- setffr /* initialize FFR */
- ptrue p1.b /* all ones; loop invariant */
-
- .p2align 4
- /* Read a vector's worth of bytes, stopping on first fault. */
-0: ldff1b z0.b, p1/z, [x0, xzr]
- rdffrs p0.b, p1/z
- b.nlast 2f
-
- /* First fault did not fail: the whole vector is valid.
- Avoid depending on the contents of FFR beyond the branch. */
- incb x0 /* speculate increment */
- cmpeq p2.b, p1/z, z0.b, z1.b /* search for c */
- cmpeq p3.b, p1/z, z0.b, 0 /* search for 0 */
- orrs p4.b, p1/z, p2.b, p3.b /* c | 0 */
- b.none 0b
- decb x0 /* undo speculate */
-
- /* Found C or 0. */
-1: brka p4.b, p1/z, p4.b /* find first such */
- sub x0, x0, 1 /* adjust pointer for that byte */
- incp x0, p4.b
-#ifndef BUILD_STRCHRNUL
- ptest p4, p2.b /* was first in c? */
- csel x0, xzr, x0, none /* if there was no c, return null */
-#endif
- ret
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparision only on the valid bytes. */
-2: cmpeq p2.b, p0/z, z0.b, z1.b /* search for c */
- cmpeq p3.b, p0/z, z0.b, 0 /* search for 0 */
- orrs p4.b, p0/z, p2.b, p3.b /* c | 0 */
- b.any 1b
-
- /* No C or 0 found. Re-init FFR, increment, and loop. */
- setffr
- incp x0, p0.b
- b 0b
-
- .size FUNC, . - FUNC
diff --git a/string/aarch64/strchr.S b/string/aarch64/strchr.S
deleted file mode 100644
index 945be3d..0000000
--- a/string/aarch64/strchr.S
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * strchr - find a character in a string
- *
- * Copyright (c) 2014-2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Neon Available.
- */
-
-/* Arguments and results. */
-#define srcin x0
-#define chrin w1
-
-#define result x0
-
-#define src x2
-#define tmp1 x3
-#define wtmp2 w4
-#define tmp3 x5
-
-#define vrepchr v0
-#define vdata1 v1
-#define vdata2 v2
-#define vhas_nul1 v3
-#define vhas_nul2 v4
-#define vhas_chr1 v5
-#define vhas_chr2 v6
-#define vrepmask_0 v7
-#define vrepmask_c v16
-#define vend1 v17
-#define vend2 v18
-
-/* Core algorithm.
-
- For each 32-byte hunk we calculate a 64-bit syndrome value, with
- two bits per byte (LSB is always in bits 0 and 1, for both big
- and little-endian systems). For each tuple, bit 0 is set iff
- the relevant byte matched the requested character; bit 1 is set
- iff the relevant byte matched the NUL end of string (we trigger
- off bit0 for the special case of looking for NUL). Since the bits
- in the syndrome reflect exactly the order in which things occur
- in the original string a count_trailing_zeros() operation will
- identify exactly which byte is causing the termination, and why. */
-
-/* Locals and temporaries. */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-def_fn __strchr_aarch64
- /* Magic constant 0x40100401 to allow us to identify which lane
- matches the requested byte. Magic constant 0x80200802 used
- similarly for NUL termination. */
- mov wtmp2, #0x0401
- movk wtmp2, #0x4010, lsl #16
- dup vrepchr.16b, chrin
- bic src, srcin, #31 /* Work with aligned 32-byte hunks. */
- dup vrepmask_c.4s, wtmp2
- ands tmp1, srcin, #31
- add vrepmask_0.4s, vrepmask_c.4s, vrepmask_c.4s /* equiv: lsl #1 */
- b.eq .Lloop
-
- /* Input string is not 32-byte aligned. Rather than forcing
- the padding bytes to a safe value, we calculate the syndrome
- for all the bytes, but then mask off those bits of the
- syndrome that are related to the padding. */
- ld1 {vdata1.16b, vdata2.16b}, [src], #32
- neg tmp1, tmp1
- cmeq vhas_nul1.16b, vdata1.16b, #0
- cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
- cmeq vhas_nul2.16b, vdata2.16b, #0
- cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
- and vhas_nul1.16b, vhas_nul1.16b, vrepmask_0.16b
- and vhas_nul2.16b, vhas_nul2.16b, vrepmask_0.16b
- and vhas_chr1.16b, vhas_chr1.16b, vrepmask_c.16b
- and vhas_chr2.16b, vhas_chr2.16b, vrepmask_c.16b
- orr vend1.16b, vhas_nul1.16b, vhas_chr1.16b
- orr vend2.16b, vhas_nul2.16b, vhas_chr2.16b
- lsl tmp1, tmp1, #1
- addp vend1.16b, vend1.16b, vend2.16b // 256->128
- mov tmp3, #~0
- addp vend1.16b, vend1.16b, vend2.16b // 128->64
- lsr tmp1, tmp3, tmp1
-
- mov tmp3, vend1.2d[0]
- bic tmp1, tmp3, tmp1 // Mask padding bits.
- cbnz tmp1, .Ltail
-
-.Lloop:
- ld1 {vdata1.16b, vdata2.16b}, [src], #32
- cmeq vhas_nul1.16b, vdata1.16b, #0
- cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
- cmeq vhas_nul2.16b, vdata2.16b, #0
- cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
- /* Use a fast check for the termination condition. */
- orr vend1.16b, vhas_nul1.16b, vhas_chr1.16b
- orr vend2.16b, vhas_nul2.16b, vhas_chr2.16b
- orr vend1.16b, vend1.16b, vend2.16b
- addp vend1.2d, vend1.2d, vend1.2d
- mov tmp1, vend1.2d[0]
- cbz tmp1, .Lloop
-
- /* Termination condition found. Now need to establish exactly why
- we terminated. */
- and vhas_nul1.16b, vhas_nul1.16b, vrepmask_0.16b
- and vhas_nul2.16b, vhas_nul2.16b, vrepmask_0.16b
- and vhas_chr1.16b, vhas_chr1.16b, vrepmask_c.16b
- and vhas_chr2.16b, vhas_chr2.16b, vrepmask_c.16b
- orr vend1.16b, vhas_nul1.16b, vhas_chr1.16b
- orr vend2.16b, vhas_nul2.16b, vhas_chr2.16b
- addp vend1.16b, vend1.16b, vend2.16b // 256->128
- addp vend1.16b, vend1.16b, vend2.16b // 128->64
-
- mov tmp1, vend1.2d[0]
-.Ltail:
- /* Count the trailing zeros, by bit reversing... */
- rbit tmp1, tmp1
- /* Re-bias source. */
- sub src, src, #32
- clz tmp1, tmp1 /* And counting the leading zeros. */
- /* Tmp1 is even if the target charager was found first. Otherwise
- we've found the end of string and we weren't looking for NUL. */
- tst tmp1, #1
- add result, src, tmp1, lsr #1
- csel result, result, xzr, eq
- ret
-
- .size __strchr_aarch64, . - __strchr_aarch64
diff --git a/string/aarch64/strchrnul-sve.S b/string/aarch64/strchrnul-sve.S
deleted file mode 100644
index 5140e59..0000000
--- a/string/aarch64/strchrnul-sve.S
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * strchrnul - find a character or nul in a string
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#define BUILD_STRCHRNUL
-#include "strchr-sve.S"
diff --git a/string/aarch64/strchrnul.S b/string/aarch64/strchrnul.S
deleted file mode 100644
index d19c0e8..0000000
--- a/string/aarch64/strchrnul.S
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * strchrnul - find a character or nul in a string
- *
- * Copyright (c) 2014-2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Neon Available.
- */
-
-/* Arguments and results. */
-#define srcin x0
-#define chrin w1
-
-#define result x0
-
-#define src x2
-#define tmp1 x3
-#define wtmp2 w4
-#define tmp3 x5
-
-#define vrepchr v0
-#define vdata1 v1
-#define vdata2 v2
-#define vhas_nul1 v3
-#define vhas_nul2 v4
-#define vhas_chr1 v5
-#define vhas_chr2 v6
-#define vrepmask v7
-#define vend1 v16
-
-/* Core algorithm.
-
- For each 32-byte hunk we calculate a 64-bit syndrome value, with
- two bits per byte (LSB is always in bits 0 and 1, for both big
- and little-endian systems). For each tuple, bit 0 is set iff
- the relevant byte matched the requested character or nul. Since the
- bits in the syndrome reflect exactly the order in which things occur
- in the original string a count_trailing_zeros() operation will
- identify exactly which byte is causing the termination. */
-
-/* Locals and temporaries. */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-def_fn __strchrnul_aarch64
- /* Magic constant 0x40100401 to allow us to identify which lane
- matches the termination condition. */
- mov wtmp2, #0x0401
- movk wtmp2, #0x4010, lsl #16
- dup vrepchr.16b, chrin
- bic src, srcin, #31 /* Work with aligned 32-byte hunks. */
- dup vrepmask.4s, wtmp2
- ands tmp1, srcin, #31
- b.eq .Lloop
-
- /* Input string is not 32-byte aligned. Rather than forcing
- the padding bytes to a safe value, we calculate the syndrome
- for all the bytes, but then mask off those bits of the
- syndrome that are related to the padding. */
- ld1 {vdata1.16b, vdata2.16b}, [src], #32
- neg tmp1, tmp1
- cmeq vhas_nul1.16b, vdata1.16b, #0
- cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
- cmeq vhas_nul2.16b, vdata2.16b, #0
- cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
- orr vhas_chr1.16b, vhas_chr1.16b, vhas_nul1.16b
- orr vhas_chr2.16b, vhas_chr2.16b, vhas_nul2.16b
- and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
- and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
- lsl tmp1, tmp1, #1
- addp vend1.16b, vhas_chr1.16b, vhas_chr2.16b // 256->128
- mov tmp3, #~0
- addp vend1.16b, vend1.16b, vend1.16b // 128->64
- lsr tmp1, tmp3, tmp1
-
- mov tmp3, vend1.2d[0]
- bic tmp1, tmp3, tmp1 // Mask padding bits.
- cbnz tmp1, .Ltail
-
-.Lloop:
- ld1 {vdata1.16b, vdata2.16b}, [src], #32
- cmeq vhas_nul1.16b, vdata1.16b, #0
- cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
- cmeq vhas_nul2.16b, vdata2.16b, #0
- cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
- /* Use a fast check for the termination condition. */
- orr vhas_chr1.16b, vhas_nul1.16b, vhas_chr1.16b
- orr vhas_chr2.16b, vhas_nul2.16b, vhas_chr2.16b
- orr vend1.16b, vhas_chr1.16b, vhas_chr2.16b
- addp vend1.2d, vend1.2d, vend1.2d
- mov tmp1, vend1.2d[0]
- cbz tmp1, .Lloop
-
- /* Termination condition found. Now need to establish exactly why
- we terminated. */
- and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
- and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
- addp vend1.16b, vhas_chr1.16b, vhas_chr2.16b // 256->128
- addp vend1.16b, vend1.16b, vend1.16b // 128->64
-
- mov tmp1, vend1.2d[0]
-.Ltail:
- /* Count the trailing zeros, by bit reversing... */
- rbit tmp1, tmp1
- /* Re-bias source. */
- sub src, src, #32
- clz tmp1, tmp1 /* ... and counting the leading zeros. */
- /* tmp1 is twice the offset into the fragment. */
- add result, src, tmp1, lsr #1
- ret
-
- .size __strchrnul_aarch64, . - __strchrnul_aarch64
diff --git a/string/aarch64/strcmp-sve.S b/string/aarch64/strcmp-sve.S
deleted file mode 100644
index 91bac19..0000000
--- a/string/aarch64/strcmp-sve.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * __strcmp_aarch64_sve - compare two strings
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
- .globl __strcmp_aarch64_sve
- .type __strcmp_aarch64_sve, %function
- .p2align 4
-__strcmp_aarch64_sve:
- setffr /* initialize FFR */
- ptrue p1.b, all /* all ones; loop invariant */
- mov x2, 0 /* initialize offset */
- nop
-
- /* Read a vector's worth of bytes, stopping on first fault. */
-0: ldff1b z0.b, p1/z, [x0, x2]
- ldff1b z1.b, p1/z, [x1, x2]
- rdffrs p0.b, p1/z
- b.nlast 2f
-
- /* First fault did not fail: the whole vector is valid.
- Avoid depending on the contents of FFR beyond the branch. */
- incb x2, all /* skip bytes for next round */
- cmpeq p2.b, p1/z, z0.b, z1.b /* compare strings */
- cmpne p3.b, p1/z, z0.b, 0 /* search for ~zero */
- nands p2.b, p1/z, p2.b, p3.b /* ~(eq & ~zero) -> ne | zero */
- b.none 0b
-
- /* Found end-of-string or inequality. */
-1: brkb p2.b, p1/z, p2.b /* find first such */
- lasta w0, p2, z0.b /* extract each char */
- lasta w1, p2, z1.b
- sub x0, x0, x1 /* return comparison */
- ret
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparison only on the valid bytes. */
-2: incp x2, p0.b /* skip bytes for next round */
- setffr /* re-init FFR for next round */
- cmpeq p2.b, p0/z, z0.b, z1.b /* compare strings, as above */
- cmpne p3.b, p0/z, z0.b, 0
- nands p2.b, p0/z, p2.b, p3.b
- b.none 0b
- b 1b
-
- .size __strcmp_aarch64_sve, . - __strcmp_aarch64_sve
diff --git a/string/aarch64/strcmp.S b/string/aarch64/strcmp.S
deleted file mode 100644
index 2aa367c..0000000
--- a/string/aarch64/strcmp.S
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * strcmp - compare two strings
- *
- * Copyright (c) 2012, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-#define L(label) .L ## label
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-/* Parameters and result. */
-#define src1 x0
-#define src2 x1
-#define result x0
-
-/* Internal variables. */
-#define data1 x2
-#define data1w w2
-#define data2 x3
-#define data2w w3
-#define has_nul x4
-#define diff x5
-#define syndrome x6
-#define tmp1 x7
-#define tmp2 x8
-#define tmp3 x9
-#define zeroones x10
-#define pos x11
-
- /* Start of performance-critical section -- one 64B cache line. */
-def_fn __strcmp_aarch64 p2align=6
- eor tmp1, src1, src2
- mov zeroones, #REP8_01
- tst tmp1, #7
- b.ne L(misaligned8)
- ands tmp1, src1, #7
- b.ne L(mutual_align)
- /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
- (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
- can be done in parallel across the entire word. */
-L(loop_aligned):
- ldr data1, [src1], #8
- ldr data2, [src2], #8
-L(start_realigned):
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- bic has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
- orr syndrome, diff, has_nul
- cbz syndrome, L(loop_aligned)
- /* End of performance-critical section -- one 64B cache line. */
-
-L(end):
-#ifndef __AARCH64EB__
- rev syndrome, syndrome
- rev data1, data1
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
- Shifting left now will bring the critical information into the
- top bits. */
- clz pos, syndrome
- rev data2, data2
- lsl data1, data1, pos
- lsl data2, data2, pos
- /* But we need to zero-extend (char is unsigned) the value and then
- perform a signed 32-bit subtraction. */
- lsr data1, data1, #56
- sub result, data1, data2, lsr #56
- ret
-#else
- /* For big-endian we cannot use the trick with the syndrome value
- as carry-propagation can corrupt the upper bits if the trailing
- bytes in the string contain 0x01. */
- /* However, if there is no NUL byte in the dword, we can generate
- the result directly. We can't just subtract the bytes as the
- MSB might be significant. */
- cbnz has_nul, 1f
- cmp data1, data2
- cset result, ne
- cneg result, result, lo
- ret
-1:
- /* Re-compute the NUL-byte detection, using a byte-reversed value. */
- rev tmp3, data1
- sub tmp1, tmp3, zeroones
- orr tmp2, tmp3, #REP8_7f
- bic has_nul, tmp1, tmp2
- rev has_nul, has_nul
- orr syndrome, diff, has_nul
- clz pos, syndrome
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
- Shifting left now will bring the critical information into the
- top bits. */
- lsl data1, data1, pos
- lsl data2, data2, pos
- /* But we need to zero-extend (char is unsigned) the value and then
- perform a signed 32-bit subtraction. */
- lsr data1, data1, #56
- sub result, data1, data2, lsr #56
- ret
-#endif
-
-L(mutual_align):
- /* Sources are mutually aligned, but are not currently at an
- alignment boundary. Round down the addresses and then mask off
- the bytes that preceed the start point. */
- bic src1, src1, #7
- bic src2, src2, #7
- lsl tmp1, tmp1, #3 /* Bytes beyond alignment -> bits. */
- ldr data1, [src1], #8
- neg tmp1, tmp1 /* Bits to alignment -64. */
- ldr data2, [src2], #8
- mov tmp2, #~0
-#ifdef __AARCH64EB__
- /* Big-endian. Early bytes are at MSB. */
- lsl tmp2, tmp2, tmp1 /* Shift (tmp1 & 63). */
-#else
- /* Little-endian. Early bytes are at LSB. */
- lsr tmp2, tmp2, tmp1 /* Shift (tmp1 & 63). */
-#endif
- orr data1, data1, tmp2
- orr data2, data2, tmp2
- b L(start_realigned)
-
-L(misaligned8):
- /* Align SRC1 to 8 bytes and then compare 8 bytes at a time, always
- checking to make sure that we don't access beyond page boundary in
- SRC2. */
- tst src1, #7
- b.eq L(loop_misaligned)
-L(do_misaligned):
- ldrb data1w, [src1], #1
- ldrb data2w, [src2], #1
- cmp data1w, #1
- ccmp data1w, data2w, #0, cs /* NZCV = 0b0000. */
- b.ne L(done)
- tst src1, #7
- b.ne L(do_misaligned)
-
-L(loop_misaligned):
- /* Test if we are within the last dword of the end of a 4K page. If
- yes then jump back to the misaligned loop to copy a byte at a time. */
- and tmp1, src2, #0xff8
- eor tmp1, tmp1, #0xff8
- cbz tmp1, L(do_misaligned)
- ldr data1, [src1], #8
- ldr data2, [src2], #8
-
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- bic has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
- orr syndrome, diff, has_nul
- cbz syndrome, L(loop_misaligned)
- b L(end)
-
-L(done):
- sub result, data1, data2
- ret
- .size __strcmp_aarch64, .-__strcmp_aarch64
diff --git a/string/aarch64/strcpy-sve.S b/string/aarch64/strcpy-sve.S
deleted file mode 100644
index c929f37..0000000
--- a/string/aarch64/strcpy-sve.S
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * strcpy/stpcpy - copy a string returning pointer to start/end.
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
-/* To build as stpcpy, define BUILD_STPCPY before compiling this file. */
-#ifdef BUILD_STPCPY
-#define FUNC __stpcpy_aarch64_sve
-#else
-#define FUNC __strcpy_aarch64_sve
-#endif
-
- .globl FUNC
- .type FUNC, %function
- .p2align 4
-FUNC:
- setffr /* initialize FFR */
- ptrue p2.b, all /* all ones; loop invariant */
- mov x2, 0 /* initialize offset */
-
- .p2align 4
- /* Read a vector's worth of bytes, stopping on first fault. */
-0: ldff1b z0.b, p2/z, [x1, x2]
- rdffrs p0.b, p2/z
- b.nlast 1f
-
- /* First fault did not fail: the whole vector is valid.
- Avoid depending on the contexts of FFR beyond the branch. */
- cmpeq p1.b, p2/z, z0.b, 0 /* search for zeros */
- b.any 2f
-
- /* No zero found. Store the whole vector and loop. */
- st1b z0.b, p2, [x0, x2]
- incb x2, all
- b 0b
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparison only on the valid bytes. */
-1: cmpeq p1.b, p0/z, z0.b, 0 /* search for zeros */
- b.any 2f
-
- /* No zero found. Store the valid portion of the vector and loop. */
- setffr /* re-init FFR */
- st1b z0.b, p0, [x0, x2]
- incp x2, p0.b
- b 0b
-
- /* Zero found. Crop the vector to the found zero and finish. */
-2: brka p0.b, p2/z, p1.b
- st1b z0.b, p0, [x0, x2]
-#ifdef BUILD_STPCPY
- add x0, x0, x2
- sub x0, x0, 1
- incp x0, p0.b
-#endif
- ret
-
- .size FUNC, . - FUNC
diff --git a/string/aarch64/strcpy.S b/string/aarch64/strcpy.S
deleted file mode 100644
index 4e10b4d..0000000
--- a/string/aarch64/strcpy.S
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * strcpy/stpcpy - copy a string returning pointer to start/end.
- *
- * Copyright (c) 2013-2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses, min page size 4k.
- */
-
-/* To build as stpcpy, define BUILD_STPCPY before compiling this file.
-
- To test the page crossing code path more thoroughly, compile with
- -DSTRCPY_TEST_PAGE_CROSS - this will force all copies through the slower
- entry path. This option is not intended for production use. */
-
-/* Arguments and results. */
-#define dstin x0
-#define srcin x1
-
-/* Locals and temporaries. */
-#define src x2
-#define dst x3
-#define data1 x4
-#define data1w w4
-#define data2 x5
-#define data2w w5
-#define has_nul1 x6
-#define has_nul2 x7
-#define tmp1 x8
-#define tmp2 x9
-#define tmp3 x10
-#define tmp4 x11
-#define zeroones x12
-#define data1a x13
-#define data2a x14
-#define pos x15
-#define len x16
-#define to_align x17
-
-#ifdef BUILD_STPCPY
-#define STRCPY __stpcpy_aarch64
-#else
-#define STRCPY __strcpy_aarch64
-#endif
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
- /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
- (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
- can be done in parallel across the entire word. */
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
- /* AArch64 systems have a minimum page size of 4k. We can do a quick
- page size check for crossing this boundary on entry and if we
- do not, then we can short-circuit much of the entry code. We
- expect early page-crossing strings to be rare (probability of
- 16/MIN_PAGE_SIZE ~= 0.4%), so the branch should be quite
- predictable, even with random strings.
-
- We don't bother checking for larger page sizes, the cost of setting
- up the correct page size is just not worth the extra gain from
- a small reduction in the cases taking the slow path. Note that
- we only care about whether the first fetch, which may be
- misaligned, crosses a page boundary - after that we move to aligned
- fetches for the remainder of the string. */
-
-#ifdef STRCPY_TEST_PAGE_CROSS
- /* Make everything that isn't Qword aligned look like a page cross. */
-#define MIN_PAGE_P2 4
-#else
-#define MIN_PAGE_P2 12
-#endif
-
-#define MIN_PAGE_SIZE (1 << MIN_PAGE_P2)
-
-def_fn STRCPY p2align=6
- /* For moderately short strings, the fastest way to do the copy is to
- calculate the length of the string in the same way as strlen, then
- essentially do a memcpy of the result. This avoids the need for
- multiple byte copies and further means that by the time we
- reach the bulk copy loop we know we can always use DWord
- accesses. We expect __strcpy_aarch64 to rarely be called repeatedly
- with the same source string, so branch prediction is likely to
- always be difficult - we mitigate against this by preferring
- conditional select operations over branches whenever this is
- feasible. */
- and tmp2, srcin, #(MIN_PAGE_SIZE - 1)
- mov zeroones, #REP8_01
- and to_align, srcin, #15
- cmp tmp2, #(MIN_PAGE_SIZE - 16)
- neg tmp1, to_align
- /* The first fetch will straddle a (possible) page boundary iff
- srcin + 15 causes bit[MIN_PAGE_P2] to change value. A 16-byte
- aligned string will never fail the page align check, so will
- always take the fast path. */
- b.gt .Lpage_cross
-
-.Lpage_cross_ok:
- ldp data1, data2, [srcin]
-#ifdef __AARCH64EB__
- /* Because we expect the end to be found within 16 characters
- (profiling shows this is the most common case), it's worth
- swapping the bytes now to save having to recalculate the
- termination syndrome later. We preserve data1 and data2
- so that we can re-use the values later on. */
- rev tmp2, data1
- sub tmp1, tmp2, zeroones
- orr tmp2, tmp2, #REP8_7f
- bics has_nul1, tmp1, tmp2
- b.ne .Lfp_le8
- rev tmp4, data2
- sub tmp3, tmp4, zeroones
- orr tmp4, tmp4, #REP8_7f
-#else
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- bics has_nul1, tmp1, tmp2
- b.ne .Lfp_le8
- sub tmp3, data2, zeroones
- orr tmp4, data2, #REP8_7f
-#endif
- bics has_nul2, tmp3, tmp4
- b.eq .Lbulk_entry
-
- /* The string is short (<=16 bytes). We don't know exactly how
- short though, yet. Work out the exact length so that we can
- quickly select the optimal copy strategy. */
-.Lfp_gt8:
- rev has_nul2, has_nul2
- clz pos, has_nul2
- mov tmp2, #56
- add dst, dstin, pos, lsr #3 /* Bits to bytes. */
- sub pos, tmp2, pos
-#ifdef __AARCH64EB__
- lsr data2, data2, pos
-#else
- lsl data2, data2, pos
-#endif
- str data2, [dst, #1]
- str data1, [dstin]
-#ifdef BUILD_STPCPY
- add dstin, dst, #8
-#endif
- ret
-
-.Lfp_le8:
- rev has_nul1, has_nul1
- clz pos, has_nul1
- add dst, dstin, pos, lsr #3 /* Bits to bytes. */
- subs tmp2, pos, #24 /* Pos in bits. */
- b.lt .Lfp_lt4
-#ifdef __AARCH64EB__
- mov tmp2, #56
- sub pos, tmp2, pos
- lsr data2, data1, pos
- lsr data1, data1, #32
-#else
- lsr data2, data1, tmp2
-#endif
- /* 4->7 bytes to copy. */
- str data2w, [dst, #-3]
- str data1w, [dstin]
-#ifdef BUILD_STPCPY
- mov dstin, dst
-#endif
- ret
-.Lfp_lt4:
- cbz pos, .Lfp_lt2
- /* 2->3 bytes to copy. */
-#ifdef __AARCH64EB__
- lsr data1, data1, #48
-#endif
- strh data1w, [dstin]
- /* Fall-through, one byte (max) to go. */
-.Lfp_lt2:
- /* Null-terminated string. Last character must be zero! */
- strb wzr, [dst]
-#ifdef BUILD_STPCPY
- mov dstin, dst
-#endif
- ret
-
- .p2align 6
- /* Aligning here ensures that the entry code and main loop all lies
- within one 64-byte cache line. */
-.Lbulk_entry:
- sub to_align, to_align, #16
- stp data1, data2, [dstin]
- sub src, srcin, to_align
- sub dst, dstin, to_align
- b .Lentry_no_page_cross
-
- /* The inner loop deals with two Dwords at a time. This has a
- slightly higher start-up cost, but we should win quite quickly,
- especially on cores with a high number of issue slots per
- cycle, as we get much better parallelism out of the operations. */
-.Lmain_loop:
- stp data1, data2, [dst], #16
-.Lentry_no_page_cross:
- ldp data1, data2, [src], #16
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- sub tmp3, data2, zeroones
- orr tmp4, data2, #REP8_7f
- bic has_nul1, tmp1, tmp2
- bics has_nul2, tmp3, tmp4
- ccmp has_nul1, #0, #0, eq /* NZCV = 0000 */
- b.eq .Lmain_loop
-
- /* Since we know we are copying at least 16 bytes, the fastest way
- to deal with the tail is to determine the location of the
- trailing NUL, then (re)copy the 16 bytes leading up to that. */
- cmp has_nul1, #0
-#ifdef __AARCH64EB__
- /* For big-endian, carry propagation (if the final byte in the
- string is 0x01) means we cannot use has_nul directly. The
- easiest way to get the correct byte is to byte-swap the data
- and calculate the syndrome a second time. */
- csel data1, data1, data2, ne
- rev data1, data1
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- bic has_nul1, tmp1, tmp2
-#else
- csel has_nul1, has_nul1, has_nul2, ne
-#endif
- rev has_nul1, has_nul1
- clz pos, has_nul1
- add tmp1, pos, #72
- add pos, pos, #8
- csel pos, pos, tmp1, ne
- add src, src, pos, lsr #3
- add dst, dst, pos, lsr #3
- ldp data1, data2, [src, #-32]
- stp data1, data2, [dst, #-16]
-#ifdef BUILD_STPCPY
- sub dstin, dst, #1
-#endif
- ret
-
-.Lpage_cross:
- bic src, srcin, #15
- /* Start by loading two words at [srcin & ~15], then forcing the
- bytes that precede srcin to 0xff. This means they never look
- like termination bytes. */
- ldp data1, data2, [src]
- lsl tmp1, tmp1, #3 /* Bytes beyond alignment -> bits. */
- tst to_align, #7
- csetm tmp2, ne
-#ifdef __AARCH64EB__
- lsl tmp2, tmp2, tmp1 /* Shift (tmp1 & 63). */
-#else
- lsr tmp2, tmp2, tmp1 /* Shift (tmp1 & 63). */
-#endif
- orr data1, data1, tmp2
- orr data2a, data2, tmp2
- cmp to_align, #8
- csinv data1, data1, xzr, lt
- csel data2, data2, data2a, lt
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- sub tmp3, data2, zeroones
- orr tmp4, data2, #REP8_7f
- bic has_nul1, tmp1, tmp2
- bics has_nul2, tmp3, tmp4
- ccmp has_nul1, #0, #0, eq /* NZCV = 0000 */
- b.eq .Lpage_cross_ok
- /* We now need to make data1 and data2 look like they've been
- loaded directly from srcin. Do a rotate on the 128-bit value. */
- lsl tmp1, to_align, #3 /* Bytes->bits. */
- neg tmp2, to_align, lsl #3
-#ifdef __AARCH64EB__
- lsl data1a, data1, tmp1
- lsr tmp4, data2, tmp2
- lsl data2, data2, tmp1
- orr tmp4, tmp4, data1a
- cmp to_align, #8
- csel data1, tmp4, data2, lt
- rev tmp2, data1
- rev tmp4, data2
- sub tmp1, tmp2, zeroones
- orr tmp2, tmp2, #REP8_7f
- sub tmp3, tmp4, zeroones
- orr tmp4, tmp4, #REP8_7f
-#else
- lsr data1a, data1, tmp1
- lsl tmp4, data2, tmp2
- lsr data2, data2, tmp1
- orr tmp4, tmp4, data1a
- cmp to_align, #8
- csel data1, tmp4, data2, lt
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- sub tmp3, data2, zeroones
- orr tmp4, data2, #REP8_7f
-#endif
- bic has_nul1, tmp1, tmp2
- cbnz has_nul1, .Lfp_le8
- bic has_nul2, tmp3, tmp4
- b .Lfp_gt8
-
- .size STRCPY, . - STRCPY
diff --git a/string/aarch64/strlen-sve.S b/string/aarch64/strlen-sve.S
deleted file mode 100644
index 64ede85..0000000
--- a/string/aarch64/strlen-sve.S
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * __strlen_aarch64_sve - compute the length of a string
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
- .globl __strlen_aarch64_sve
- .type __strlen_aarch64_sve, %function
- .p2align 4
-__strlen_aarch64_sve:
- setffr /* initialize FFR */
- ptrue p2.b /* all ones; loop invariant */
- mov x1, 0 /* initialize length */
- nop
-
- /* Read a vector's worth of bytes, stopping on first fault. */
-0: ldff1b z0.b, p2/z, [x0, x1]
- nop
- rdffrs p0.b, p2/z
- b.nlast 2f
-
- /* First fault did not fail: the whole vector is valid.
- Avoid depending on the contents of FFR beyond the branch. */
- incb x1, all /* speculate increment */
- cmpeq p1.b, p2/z, z0.b, 0 /* loop if no zeros */
- b.none 0b
- decb x1, all /* undo speculate */
-
- /* Zero found. Select the bytes before the first and count them. */
-1: brkb p0.b, p2/z, p1.b
- incp x1, p0.b
- mov x0, x1
- ret
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparison only on the valid bytes. */
-2: cmpeq p1.b, p0/z, z0.b, 0
- b.any 1b
-
- /* No zero found. Re-init FFR, increment, and loop. */
- setffr
- incp x1, p0.b
- b 0b
-
- .size __strlen_aarch64_sve, . - __strlen_aarch64_sve
diff --git a/string/aarch64/strlen.S b/string/aarch64/strlen.S
deleted file mode 100644
index 26388d7..0000000
--- a/string/aarch64/strlen.S
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * strlen - calculate the length of a string
- *
- * Copyright (c) 2013, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses, min page size 4k.
- */
-
-/* To test the page crossing code path more thoroughly, compile with
- -DTEST_PAGE_CROSS - this will force all calls through the slower
- entry path. This option is not intended for production use. */
-
-/* Arguments and results. */
-#define srcin x0
-#define len x0
-
-/* Locals and temporaries. */
-#define src x1
-#define data1 x2
-#define data2 x3
-#define has_nul1 x4
-#define has_nul2 x5
-#define tmp1 x4
-#define tmp2 x5
-#define tmp3 x6
-#define tmp4 x7
-#define zeroones x8
-
-#define L(l) .L ## l
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
- /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
- (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
- can be done in parallel across the entire word. A faster check
- (X - 1) & 0x80 is zero for non-NUL ASCII characters, but gives
- false hits for characters 129..255. */
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-#ifdef TEST_PAGE_CROSS
-# define MIN_PAGE_SIZE 15
-#else
-# define MIN_PAGE_SIZE 4096
-#endif
-
- /* Since strings are short on average, we check the first 16 bytes
- of the string for a NUL character. In order to do an unaligned ldp
- safely we have to do a page cross check first. If there is a NUL
- byte we calculate the length from the 2 8-byte words using
- conditional select to reduce branch mispredictions (it is unlikely
- __strlen_aarch64 will be repeatedly called on strings with the same length).
-
- If the string is longer than 16 bytes, we align src so don't need
- further page cross checks, and process 32 bytes per iteration
- using the fast NUL check. If we encounter non-ASCII characters,
- fallback to a second loop using the full NUL check.
-
- If the page cross check fails, we read 16 bytes from an aligned
- address, remove any characters before the string, and continue
- in the main loop using aligned loads. Since strings crossing a
- page in the first 16 bytes are rare (probability of
- 16/MIN_PAGE_SIZE ~= 0.4%), this case does not need to be optimized.
-
- AArch64 systems have a minimum page size of 4k. We don't bother
- checking for larger page sizes - the cost of setting up the correct
- page size is just not worth the extra gain from a small reduction in
- the cases taking the slow path. Note that we only care about
- whether the first fetch, which may be misaligned, crosses a page
- boundary. */
-
-def_fn __strlen_aarch64 p2align=6
- and tmp1, srcin, MIN_PAGE_SIZE - 1
- mov zeroones, REP8_01
- cmp tmp1, MIN_PAGE_SIZE - 16
- b.gt L(page_cross)
- ldp data1, data2, [srcin]
-#ifdef __AARCH64EB__
- /* For big-endian, carry propagation (if the final byte in the
- string is 0x01) means we cannot use has_nul1/2 directly.
- Since we expect strings to be small and early-exit,
- byte-swap the data now so has_null1/2 will be correct. */
- rev data1, data1
- rev data2, data2
-#endif
- sub tmp1, data1, zeroones
- orr tmp2, data1, REP8_7f
- sub tmp3, data2, zeroones
- orr tmp4, data2, REP8_7f
- bics has_nul1, tmp1, tmp2
- bic has_nul2, tmp3, tmp4
- ccmp has_nul2, 0, 0, eq
- beq L(main_loop_entry)
-
- /* Enter with C = has_nul1 == 0. */
- csel has_nul1, has_nul1, has_nul2, cc
- mov len, 8
- rev has_nul1, has_nul1
- clz tmp1, has_nul1
- csel len, xzr, len, cc
- add len, len, tmp1, lsr 3
- ret
-
- /* The inner loop processes 32 bytes per iteration and uses the fast
- NUL check. If we encounter non-ASCII characters, use a second
- loop with the accurate NUL check. */
- .p2align 4
-L(main_loop_entry):
- bic src, srcin, 15
- sub src, src, 16
-L(main_loop):
- ldp data1, data2, [src, 32]!
-.Lpage_cross_entry:
- sub tmp1, data1, zeroones
- sub tmp3, data2, zeroones
- orr tmp2, tmp1, tmp3
- tst tmp2, zeroones, lsl 7
- bne 1f
- ldp data1, data2, [src, 16]
- sub tmp1, data1, zeroones
- sub tmp3, data2, zeroones
- orr tmp2, tmp1, tmp3
- tst tmp2, zeroones, lsl 7
- beq L(main_loop)
- add src, src, 16
-1:
- /* The fast check failed, so do the slower, accurate NUL check. */
- orr tmp2, data1, REP8_7f
- orr tmp4, data2, REP8_7f
- bics has_nul1, tmp1, tmp2
- bic has_nul2, tmp3, tmp4
- ccmp has_nul2, 0, 0, eq
- beq L(nonascii_loop)
-
- /* Enter with C = has_nul1 == 0. */
-L(tail):
-#ifdef __AARCH64EB__
- /* For big-endian, carry propagation (if the final byte in the
- string is 0x01) means we cannot use has_nul1/2 directly. The
- easiest way to get the correct byte is to byte-swap the data
- and calculate the syndrome a second time. */
- csel data1, data1, data2, cc
- rev data1, data1
- sub tmp1, data1, zeroones
- orr tmp2, data1, REP8_7f
- bic has_nul1, tmp1, tmp2
-#else
- csel has_nul1, has_nul1, has_nul2, cc
-#endif
- sub len, src, srcin
- rev has_nul1, has_nul1
- add tmp2, len, 8
- clz tmp1, has_nul1
- csel len, len, tmp2, cc
- add len, len, tmp1, lsr 3
- ret
-
-L(nonascii_loop):
- ldp data1, data2, [src, 16]!
- sub tmp1, data1, zeroones
- orr tmp2, data1, REP8_7f
- sub tmp3, data2, zeroones
- orr tmp4, data2, REP8_7f
- bics has_nul1, tmp1, tmp2
- bic has_nul2, tmp3, tmp4
- ccmp has_nul2, 0, 0, eq
- bne L(tail)
- ldp data1, data2, [src, 16]!
- sub tmp1, data1, zeroones
- orr tmp2, data1, REP8_7f
- sub tmp3, data2, zeroones
- orr tmp4, data2, REP8_7f
- bics has_nul1, tmp1, tmp2
- bic has_nul2, tmp3, tmp4
- ccmp has_nul2, 0, 0, eq
- beq L(nonascii_loop)
- b L(tail)
-
- /* Load 16 bytes from [srcin & ~15] and force the bytes that precede
- srcin to 0x7f, so we ignore any NUL bytes before the string.
- Then continue in the aligned loop. */
-L(page_cross):
- bic src, srcin, 15
- ldp data1, data2, [src]
- lsl tmp1, srcin, 3
- mov tmp4, -1
-#ifdef __AARCH64EB__
- /* Big-endian. Early bytes are at MSB. */
- lsr tmp1, tmp4, tmp1 /* Shift (tmp1 & 63). */
-#else
- /* Little-endian. Early bytes are at LSB. */
- lsl tmp1, tmp4, tmp1 /* Shift (tmp1 & 63). */
-#endif
- orr tmp1, tmp1, REP8_80
- orn data1, data1, tmp1
- orn tmp2, data2, tmp1
- tst srcin, 8
- csel data1, data1, tmp4, eq
- csel data2, data2, tmp2, eq
- b L(page_cross_entry)
-
- .size __strlen_aarch64, . - __strlen_aarch64
diff --git a/string/aarch64/strncmp-sve.S b/string/aarch64/strncmp-sve.S
deleted file mode 100644
index 6f31eca..0000000
--- a/string/aarch64/strncmp-sve.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * strncmp - compare two strings with limit
- *
- * Copyright (c) 2018, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
- .globl __strncmp_aarch64_sve
- .type __strncmp_aarch64_sve, %function
- .p2align 4
-__strncmp_aarch64_sve:
- setffr /* initialize FFR */
- mov x3, 0 /* initialize off */
-
-0: whilelo p0.b, x3, x2 /* while off < max */
- b.none 9f
-
- ldff1b z0.b, p0/z, [x0, x3]
- ldff1b z1.b, p0/z, [x1, x3]
- rdffrs p1.b, p0/z
- b.nlast 2f
-
- /* First fault did not fail: the vector up to max is valid.
- Avoid depending on the contents of FFR beyond the branch.
- Increment for a whole vector, even if we've only read a partial.
- This is significantly cheaper than INCP, and since OFF is not
- used after the loop it is ok to increment OFF past MAX. */
- incb x3
- cmpeq p1.b, p0/z, z0.b, z1.b /* compare strings */
- cmpne p2.b, p0/z, z0.b, 0 /* search for ~zero */
- nands p2.b, p0/z, p1.b, p2.b /* ~(eq & ~zero) -> ne | zero */
- b.none 0b
-
- /* Found end-of-string or inequality. */
-1: brkb p2.b, p0/z, p2.b /* find first such */
- lasta w0, p2, z0.b /* extract each char */
- lasta w1, p2, z1.b
- sub x0, x0, x1 /* return comparison */
- ret
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparison only on the valid bytes. */
-2: cmpeq p2.b, p1/z, z0.b, z1.b /* compare strings, as above */
- cmpne p3.b, p1/z, z0.b, 0
- nands p2.b, p1/z, p2.b, p3.b
- b.any 1b
-
- /* No inequality or zero found. Re-init FFR, incr and loop. */
- setffr
- incp x3, p1.b
- b 0b
-
- /* Found end-of-count. */
-9: mov x0, 0 /* return equal */
- ret
-
- .size __strncmp_aarch64_sve, . - __strncmp_aarch64_sve
diff --git a/string/aarch64/strncmp.S b/string/aarch64/strncmp.S
deleted file mode 100644
index ced72b9..0000000
--- a/string/aarch64/strncmp.S
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * strncmp - compare two strings
- *
- * Copyright (c) 2013, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-/* Parameters and result. */
-#define src1 x0
-#define src2 x1
-#define limit x2
-#define result x0
-
-/* Internal variables. */
-#define data1 x3
-#define data1w w3
-#define data2 x4
-#define data2w w4
-#define has_nul x5
-#define diff x6
-#define syndrome x7
-#define tmp1 x8
-#define tmp2 x9
-#define tmp3 x10
-#define zeroones x11
-#define pos x12
-#define limit_wd x13
-#define mask x14
-#define endloop x15
-#define count mask
-
- .text
- .p2align 6
- .rep 7
- nop /* Pad so that the loop below fits a cache line. */
- .endr
-def_fn __strncmp_aarch64
- cbz limit, .Lret0
- eor tmp1, src1, src2
- mov zeroones, #REP8_01
- tst tmp1, #7
- and count, src1, #7
- b.ne .Lmisaligned8
- cbnz count, .Lmutual_align
- /* Calculate the number of full and partial words -1. */
- sub limit_wd, limit, #1 /* limit != 0, so no underflow. */
- lsr limit_wd, limit_wd, #3 /* Convert to Dwords. */
-
- /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
- (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
- can be done in parallel across the entire word. */
- /* Start of performance-critical section -- one 64B cache line. */
-.Lloop_aligned:
- ldr data1, [src1], #8
- ldr data2, [src2], #8
-.Lstart_realigned:
- subs limit_wd, limit_wd, #1
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- csinv endloop, diff, xzr, pl /* Last Dword or differences. */
- bics has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
- ccmp endloop, #0, #0, eq
- b.eq .Lloop_aligned
- /* End of performance-critical section -- one 64B cache line. */
-
- /* Not reached the limit, must have found the end or a diff. */
- tbz limit_wd, #63, .Lnot_limit
-
- /* Limit % 8 == 0 => all bytes significant. */
- ands limit, limit, #7
- b.eq .Lnot_limit
-
- lsl limit, limit, #3 /* Bits -> bytes. */
- mov mask, #~0
-#ifdef __AARCH64EB__
- lsr mask, mask, limit
-#else
- lsl mask, mask, limit
-#endif
- bic data1, data1, mask
- bic data2, data2, mask
-
- /* Make sure that the NUL byte is marked in the syndrome. */
- orr has_nul, has_nul, mask
-
-.Lnot_limit:
- orr syndrome, diff, has_nul
-
-#ifndef __AARCH64EB__
- rev syndrome, syndrome
- rev data1, data1
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
- Shifting left now will bring the critical information into the
- top bits. */
- clz pos, syndrome
- rev data2, data2
- lsl data1, data1, pos
- lsl data2, data2, pos
- /* But we need to zero-extend (char is unsigned) the value and then
- perform a signed 32-bit subtraction. */
- lsr data1, data1, #56
- sub result, data1, data2, lsr #56
- ret
-#else
- /* For big-endian we cannot use the trick with the syndrome value
- as carry-propagation can corrupt the upper bits if the trailing
- bytes in the string contain 0x01. */
- /* However, if there is no NUL byte in the dword, we can generate
- the result directly. We can't just subtract the bytes as the
- MSB might be significant. */
- cbnz has_nul, 1f
- cmp data1, data2
- cset result, ne
- cneg result, result, lo
- ret
-1:
- /* Re-compute the NUL-byte detection, using a byte-reversed value. */
- rev tmp3, data1
- sub tmp1, tmp3, zeroones
- orr tmp2, tmp3, #REP8_7f
- bic has_nul, tmp1, tmp2
- rev has_nul, has_nul
- orr syndrome, diff, has_nul
- clz pos, syndrome
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
- Shifting left now will bring the critical information into the
- top bits. */
- lsl data1, data1, pos
- lsl data2, data2, pos
- /* But we need to zero-extend (char is unsigned) the value and then
- perform a signed 32-bit subtraction. */
- lsr data1, data1, #56
- sub result, data1, data2, lsr #56
- ret
-#endif
-
-.Lmutual_align:
- /* Sources are mutually aligned, but are not currently at an
- alignment boundary. Round down the addresses and then mask off
- the bytes that precede the start point.
- We also need to adjust the limit calculations, but without
- overflowing if the limit is near ULONG_MAX. */
- bic src1, src1, #7
- bic src2, src2, #7
- ldr data1, [src1], #8
- neg tmp3, count, lsl #3 /* 64 - bits(bytes beyond align). */
- ldr data2, [src2], #8
- mov tmp2, #~0
- sub limit_wd, limit, #1 /* limit != 0, so no underflow. */
-#ifdef __AARCH64EB__
- /* Big-endian. Early bytes are at MSB. */
- lsl tmp2, tmp2, tmp3 /* Shift (count & 63). */
-#else
- /* Little-endian. Early bytes are at LSB. */
- lsr tmp2, tmp2, tmp3 /* Shift (count & 63). */
-#endif
- and tmp3, limit_wd, #7
- lsr limit_wd, limit_wd, #3
- /* Adjust the limit. Only low 3 bits used, so overflow irrelevant. */
- add limit, limit, count
- add tmp3, tmp3, count
- orr data1, data1, tmp2
- orr data2, data2, tmp2
- add limit_wd, limit_wd, tmp3, lsr #3
- b .Lstart_realigned
-
- .p2align 6
- /* Don't bother with dwords for up to 16 bytes. */
-.Lmisaligned8:
- cmp limit, #16
- b.hs .Ltry_misaligned_words
-
-.Lbyte_loop:
- /* Perhaps we can do better than this. */
- ldrb data1w, [src1], #1
- ldrb data2w, [src2], #1
- subs limit, limit, #1
- ccmp data1w, #1, #0, hi /* NZCV = 0b0000. */
- ccmp data1w, data2w, #0, cs /* NZCV = 0b0000. */
- b.eq .Lbyte_loop
-.Ldone:
- sub result, data1, data2
- ret
- /* Align the SRC1 to a dword by doing a bytewise compare and then do
- the dword loop. */
-.Ltry_misaligned_words:
- lsr limit_wd, limit, #3
- cbz count, .Ldo_misaligned
-
- neg count, count
- and count, count, #7
- sub limit, limit, count
- lsr limit_wd, limit, #3
-
-.Lpage_end_loop:
- ldrb data1w, [src1], #1
- ldrb data2w, [src2], #1
- cmp data1w, #1
- ccmp data1w, data2w, #0, cs /* NZCV = 0b0000. */
- b.ne .Ldone
- subs count, count, #1
- b.hi .Lpage_end_loop
-
-.Ldo_misaligned:
- /* Prepare ourselves for the next page crossing. Unlike the aligned
- loop, we fetch 1 less dword because we risk crossing bounds on
- SRC2. */
- mov count, #8
- subs limit_wd, limit_wd, #1
- b.lo .Ldone_loop
-.Lloop_misaligned:
- and tmp2, src2, #0xff8
- eor tmp2, tmp2, #0xff8
- cbz tmp2, .Lpage_end_loop
-
- ldr data1, [src1], #8
- ldr data2, [src2], #8
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- bics has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
- ccmp diff, #0, #0, eq
- b.ne .Lnot_limit
- subs limit_wd, limit_wd, #1
- b.pl .Lloop_misaligned
-
-.Ldone_loop:
- /* We found a difference or a NULL before the limit was reached. */
- and limit, limit, #7
- cbz limit, .Lnot_limit
- /* Read the last word. */
- sub src1, src1, 8
- sub src2, src2, 8
- ldr data1, [src1, limit]
- ldr data2, [src2, limit]
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- bics has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
- ccmp diff, #0, #0, eq
- b.ne .Lnot_limit
-
-.Lret0:
- mov result, #0
- ret
- .size __strncmp_aarch64, . - __strncmp_aarch64
diff --git a/string/aarch64/strnlen-sve.S b/string/aarch64/strnlen-sve.S
deleted file mode 100644
index 3a9be08..0000000
--- a/string/aarch64/strnlen-sve.S
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * strnlen - calculate the length of a string with limit.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
- .globl __strnlen_aarch64_sve
- .type __strnlen_aarch64_sve, %function
- .p2align 4
-__strnlen_aarch64_sve:
- setffr /* initialize FFR */
- mov x2, 0 /* initialize len */
- b 1f
-
- .p2align 4
- /* We have off + vl <= max, and so may read the whole vector. */
-0: ldff1b z0.b, p0/z, [x0, x2]
- rdffrs p1.b, p0/z
- b.nlast 2f
-
- /* First fault did not fail: the whole vector is valid.
- Avoid depending on the contents of FFR beyond the branch. */
- cmpeq p2.b, p0/z, z0.b, 0
- b.any 8f
- incb x2
-
-1: whilelo p0.b, x2, x1
- b.last 0b
-
- /* We have off + vl < max. Test for off == max before proceeding. */
- b.none 9f
-
- ldff1b z0.b, p0/z, [x0, x2]
- rdffrs p1.b, p0/z
- b.nlast 2f
-
- /* First fault did not fail: the vector up to max is valid.
- Avoid depending on the contents of FFR beyond the branch.
- Compare for end-of-string, but there are no more bytes. */
- cmpeq p2.b, p0/z, z0.b, 0
-
- /* Found end-of-string or zero. */
-8: brkb p2.b, p0/z, p2.b
- mov x0, x2
- incp x0, p2.b
- ret
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparison only on the valid bytes. */
-2: cmpeq p2.b, p1/z, z0.b, 0
- b.any 8b
-
- /* No inequality or zero found. Re-init FFR, incr and loop. */
- setffr
- incp x2, p1.b
- b 1b
-
- /* End of count. Return max. */
-9: mov x0, x2
- ret
-
- .size __strnlen_aarch64_sve, . - __strnlen_aarch64_sve
diff --git a/string/aarch64/strnlen.S b/string/aarch64/strnlen.S
deleted file mode 100644
index b02c846..0000000
--- a/string/aarch64/strnlen.S
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * strnlen - calculate the length of a string with limit.
- *
- * Copyright (c) 2013, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- */
-
-/* Arguments and results. */
-#define srcin x0
-#define len x0
-#define limit x1
-
-/* Locals and temporaries. */
-#define src x2
-#define data1 x3
-#define data2 x4
-#define data2a x5
-#define has_nul1 x6
-#define has_nul2 x7
-#define tmp1 x8
-#define tmp2 x9
-#define tmp3 x10
-#define tmp4 x11
-#define zeroones x12
-#define pos x13
-#define limit_wd x14
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
- .text
- .p2align 6
-.Lstart:
- /* Pre-pad to ensure critical loop begins an icache line. */
- .rep 7
- nop
- .endr
- /* Put this code here to avoid wasting more space with pre-padding. */
-.Lhit_limit:
- mov len, limit
- ret
-
-def_fn __strnlen_aarch64
- cbz limit, .Lhit_limit
- mov zeroones, #REP8_01
- bic src, srcin, #15
- ands tmp1, srcin, #15
- b.ne .Lmisaligned
- /* Calculate the number of full and partial words -1. */
- sub limit_wd, limit, #1 /* Limit != 0, so no underflow. */
- lsr limit_wd, limit_wd, #4 /* Convert to Qwords. */
-
- /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
- (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
- can be done in parallel across the entire word. */
- /* The inner loop deals with two Dwords at a time. This has a
- slightly higher start-up cost, but we should win quite quickly,
- especially on cores with a high number of issue slots per
- cycle, as we get much better parallelism out of the operations. */
-
- /* Start of critial section -- keep to one 64Byte cache line. */
-.Lloop:
- ldp data1, data2, [src], #16
-.Lrealigned:
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- sub tmp3, data2, zeroones
- orr tmp4, data2, #REP8_7f
- bic has_nul1, tmp1, tmp2
- bic has_nul2, tmp3, tmp4
- subs limit_wd, limit_wd, #1
- orr tmp1, has_nul1, has_nul2
- ccmp tmp1, #0, #0, pl /* NZCV = 0000 */
- b.eq .Lloop
- /* End of critical section -- keep to one 64Byte cache line. */
-
- orr tmp1, has_nul1, has_nul2
- cbz tmp1, .Lhit_limit /* No null in final Qword. */
-
- /* We know there's a null in the final Qword. The easiest thing
- to do now is work out the length of the string and return
- MIN (len, limit). */
-
- sub len, src, srcin
- cbz has_nul1, .Lnul_in_data2
-#ifdef __AARCH64EB__
- mov data2, data1
-#endif
- sub len, len, #8
- mov has_nul2, has_nul1
-.Lnul_in_data2:
-#ifdef __AARCH64EB__
- /* For big-endian, carry propagation (if the final byte in the
- string is 0x01) means we cannot use has_nul directly. The
- easiest way to get the correct byte is to byte-swap the data
- and calculate the syndrome a second time. */
- rev data2, data2
- sub tmp1, data2, zeroones
- orr tmp2, data2, #REP8_7f
- bic has_nul2, tmp1, tmp2
-#endif
- sub len, len, #8
- rev has_nul2, has_nul2
- clz pos, has_nul2
- add len, len, pos, lsr #3 /* Bits to bytes. */
- cmp len, limit
- csel len, len, limit, ls /* Return the lower value. */
- ret
-
-.Lmisaligned:
- /* Deal with a partial first word.
- We're doing two things in parallel here;
- 1) Calculate the number of words (but avoiding overflow if
- limit is near ULONG_MAX) - to do this we need to work out
- limit + tmp1 - 1 as a 65-bit value before shifting it;
- 2) Load and mask the initial data words - we force the bytes
- before the ones we are interested in to 0xff - this ensures
- early bytes will not hit any zero detection. */
- sub limit_wd, limit, #1
- neg tmp4, tmp1
- cmp tmp1, #8
-
- and tmp3, limit_wd, #15
- lsr limit_wd, limit_wd, #4
- mov tmp2, #~0
-
- ldp data1, data2, [src], #16
- lsl tmp4, tmp4, #3 /* Bytes beyond alignment -> bits. */
- add tmp3, tmp3, tmp1
-
-#ifdef __AARCH64EB__
- /* Big-endian. Early bytes are at MSB. */
- lsl tmp2, tmp2, tmp4 /* Shift (tmp1 & 63). */
-#else
- /* Little-endian. Early bytes are at LSB. */
- lsr tmp2, tmp2, tmp4 /* Shift (tmp1 & 63). */
-#endif
- add limit_wd, limit_wd, tmp3, lsr #4
-
- orr data1, data1, tmp2
- orr data2a, data2, tmp2
-
- csinv data1, data1, xzr, le
- csel data2, data2, data2a, le
- b .Lrealigned
- .size __strnlen_aarch64, . - .Lstart /* Include pre-padding in size. */
diff --git a/string/aarch64/strrchr-sve.S b/string/aarch64/strrchr-sve.S
deleted file mode 100644
index bb522e7..0000000
--- a/string/aarch64/strrchr-sve.S
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * strrchr - find the last of a character in a string
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * SVE Available.
- */
-
- .arch armv8-a+sve
- .text
-
- .globl __strrchr_aarch64_sve
- .type __strrchr_aarch64_sve, %function
- .p2align 4
-__strrchr_aarch64_sve:
- dup z1.b, w1 /* replicate byte across vector */
- setffr /* initialize FFR */
- ptrue p1.b /* all ones; loop invariant */
- mov x2, 0 /* no match found so far */
- pfalse p2.b
-
- .p2align 4
- /* Read a vector's worth of bytes, stopping on first fault. */
-0: ldff1b z0.b, p1/z, [x0, xzr]
- rdffrs p0.b, p1/z
- b.nlast 1f
-
- /* First fault did not fail: the whole vector is valid.
- Avoid depending on the contents of FFR beyond the branch. */
- incb x0, all /* skip bytes this round */
- cmpeq p3.b, p1/z, z0.b, 0 /* search for 0 */
- b.any 3f
-
- cmpeq p3.b, p1/z, z0.b, z1.b /* search for c; no eos */
- b.none 0b
-
- mov x2, x0 /* save advanced base */
- mov p2.b, p3.b /* save current search */
- b 0b
-
- /* First fault failed: only some of the vector is valid.
- Perform the comparisions only on the valid bytes. */
-1: cmpeq p3.b, p0/z, z0.b, 0 /* search for 0 */
- b.any 2f
-
- cmpeq p3.b, p0/z, z0.b, z1.b /* search for c; no eos */
- mov x3, x0
- incp x0, p0.b /* skip bytes this round */
- setffr /* re-init FFR */
- b.none 0b
-
- addvl x2, x3, 1 /* save advanced base */
- mov p2.b, p3.b /* save current search */
- b 0b
-
- /* Found end-of-string. */
-2: incb x0, all /* advance base */
-3: brka p3.b, p1/z, p3.b /* mask after first 0 */
- cmpeq p3.b, p3/z, z0.b, z1.b /* search for c not after eos */
- b.any 4f
-
- /* No C within last vector. Did we have one before? */
- cbz x2, 5f
- mov x0, x2 /* restore advanced base */
- mov p3.b, p2.b /* restore saved search */
-
- /* Find the *last* match in the predicate. This is slightly
- more complicated than finding the first match. */
-4: rev p3.b, p3.b /* reverse the bits */
- brka p3.b, p1/z, p3.b /* find position of last match */
- decp x0, p3.b /* retard pointer to last match */
- ret
-
- /* No C whatsoever. Return NULL. */
-5: mov x0, 0
- ret
-
- .size __strrchr_aarch64_sve, . - __strrchr_aarch64_sve
diff --git a/string/arm/memchr.S b/string/arm/memchr.S
deleted file mode 100644
index 2eff4d1..0000000
--- a/string/arm/memchr.S
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * memchr - scan memory for a character
- *
- * Copyright (c) 2010, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/*
- Written by Dave Gilbert <david.gilbert@linaro.org>
-
- This __memchr_arm routine is optimised on a Cortex-A9 and should work on
- all ARMv7 processors. It has a fast past for short sizes, and has
- an optimised path for large data sets; the worst case is finding the
- match early in a large data set.
-
- */
-
-@ 2011-02-07 david.gilbert@linaro.org
-@ Extracted from local git a5b438d861
-@ 2011-07-14 david.gilbert@linaro.org
-@ Import endianness fix from local git ea786f1b
-@ 2011-12-07 david.gilbert@linaro.org
-@ Removed unneeded cbz from align loop
-
- .syntax unified
- .arch armv7-a
-
-@ this lets us check a flag in a 00/ff byte easily in either endianness
-#ifdef __ARMEB__
-#define CHARTSTMASK(c) 1<<(31-(c*8))
-#else
-#define CHARTSTMASK(c) 1<<(c*8)
-#endif
- .text
- .thumb
-
-@ ---------------------------------------------------------------------------
- .thumb_func
- .align 2
- .p2align 4,,15
- .global __memchr_arm
- .type __memchr_arm,%function
-__memchr_arm:
- @ r0 = start of memory to scan
- @ r1 = character to look for
- @ r2 = length
- @ returns r0 = pointer to character or NULL if not found
- and r1,r1,#0xff @ Don't think we can trust the caller to actually pass a char
-
- cmp r2,#16 @ If it's short don't bother with anything clever
- blt 20f
-
- tst r0, #7 @ If it's already aligned skip the next bit
- beq 10f
-
- @ Work up to an aligned point
-5:
- ldrb r3, [r0],#1
- subs r2, r2, #1
- cmp r3, r1
- beq 50f @ If it matches exit found
- tst r0, #7
- bne 5b @ If not aligned yet then do next byte
-
-10:
- @ At this point, we are aligned, we know we have at least 8 bytes to work with
- push {r4,r5,r6,r7}
- orr r1, r1, r1, lsl #8 @ expand the match word across to all bytes
- orr r1, r1, r1, lsl #16
- bic r4, r2, #7 @ Number of double words to work with
- mvns r7, #0 @ all F's
- movs r3, #0
-
-15:
- ldmia r0!,{r5,r6}
- subs r4, r4, #8
- eor r5,r5, r1 @ Get it so that r5,r6 have 00's where the bytes match the target
- eor r6,r6, r1
- uadd8 r5, r5, r7 @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
- sel r5, r3, r7 @ bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
- uadd8 r6, r6, r7 @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
- sel r6, r5, r7 @ chained....bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
- cbnz r6, 60f
- bne 15b @ (Flags from the subs above) If not run out of bytes then go around again
-
- pop {r4,r5,r6,r7}
- and r1,r1,#0xff @ Get r1 back to a single character from the expansion above
- and r2,r2,#7 @ Leave the count remaining as the number after the double words have been done
-
-20:
- cbz r2, 40f @ 0 length or hit the end already then not found
-
-21: @ Post aligned section, or just a short call
- ldrb r3,[r0],#1
- subs r2,r2,#1
- eor r3,r3,r1 @ r3 = 0 if match - doesn't break flags from sub
- cbz r3, 50f
- bne 21b @ on r2 flags
-
-40:
- movs r0,#0 @ not found
- bx lr
-
-50:
- subs r0,r0,#1 @ found
- bx lr
-
-60: @ We're here because the fast path found a hit - now we have to track down exactly which word it was
- @ r0 points to the start of the double word after the one that was tested
- @ r5 has the 00/ff pattern for the first word, r6 has the chained value
- cmp r5, #0
- itte eq
- moveq r5, r6 @ the end is in the 2nd word
- subeq r0,r0,#3 @ Points to 2nd byte of 2nd word
- subne r0,r0,#7 @ or 2nd byte of 1st word
-
- @ r0 currently points to the 3rd byte of the word containing the hit
- tst r5, # CHARTSTMASK(0) @ 1st character
- bne 61f
- adds r0,r0,#1
- tst r5, # CHARTSTMASK(1) @ 2nd character
- ittt eq
- addeq r0,r0,#1
- tsteq r5, # (3<<15) @ 2nd & 3rd character
- @ If not the 3rd must be the last one
- addeq r0,r0,#1
-
-61:
- pop {r4,r5,r6,r7}
- subs r0,r0,#1
- bx lr
-
- .size __memchr_arm, . - __memchr_arm
diff --git a/string/arm/memcpy.S b/string/arm/memcpy.S
deleted file mode 100644
index 3346e4f..0000000
--- a/string/arm/memcpy.S
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * memcpy - copy memory area
- *
- * Copyright (c) 2013, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/*
- This memcpy routine is optimised for Cortex-A15 cores and takes advantage
- of VFP or NEON when built with the appropriate flags.
-
- Assumptions:
-
- ARMv6 (ARMv7-a if using Neon)
- ARM state
- Unaligned accesses
-
- */
-
- .syntax unified
- /* This implementation requires ARM state. */
- .arm
-
-#ifdef __ARM_NEON__
-
- .fpu neon
- .arch armv7-a
-# define FRAME_SIZE 4
-# define USE_VFP
-# define USE_NEON
-
-#elif !defined (__SOFTFP__)
-
- .arch armv6
- .fpu vfpv2
-# define FRAME_SIZE 32
-# define USE_VFP
-
-#else
- .arch armv6
-# define FRAME_SIZE 32
-
-#endif
-
-/* Old versions of GAS incorrectly implement the NEON align semantics. */
-#ifdef BROKEN_ASM_NEON_ALIGN
-#define ALIGN(addr, align) addr,:align
-#else
-#define ALIGN(addr, align) addr:align
-#endif
-
-#define PC_OFFSET 8 /* PC pipeline compensation. */
-#define INSN_SIZE 4
-
-/* Call parameters. */
-#define dstin r0
-#define src r1
-#define count r2
-
-/* Locals. */
-#define tmp1 r3
-#define dst ip
-#define tmp2 r10
-
-#ifndef USE_NEON
-/* For bulk copies using GP registers. */
-#define A_l r2 /* Call-clobbered. */
-#define A_h r3 /* Call-clobbered. */
-#define B_l r4
-#define B_h r5
-#define C_l r6
-#define C_h r7
-#define D_l r8
-#define D_h r9
-#endif
-
-/* Number of lines ahead to pre-fetch data. If you change this the code
- below will need adjustment to compensate. */
-
-#define prefetch_lines 5
-
-#ifdef USE_VFP
- .macro cpy_line_vfp vreg, base
- vstr \vreg, [dst, #\base]
- vldr \vreg, [src, #\base]
- vstr d0, [dst, #\base + 8]
- vldr d0, [src, #\base + 8]
- vstr d1, [dst, #\base + 16]
- vldr d1, [src, #\base + 16]
- vstr d2, [dst, #\base + 24]
- vldr d2, [src, #\base + 24]
- vstr \vreg, [dst, #\base + 32]
- vldr \vreg, [src, #\base + prefetch_lines * 64 - 32]
- vstr d0, [dst, #\base + 40]
- vldr d0, [src, #\base + 40]
- vstr d1, [dst, #\base + 48]
- vldr d1, [src, #\base + 48]
- vstr d2, [dst, #\base + 56]
- vldr d2, [src, #\base + 56]
- .endm
-
- .macro cpy_tail_vfp vreg, base
- vstr \vreg, [dst, #\base]
- vldr \vreg, [src, #\base]
- vstr d0, [dst, #\base + 8]
- vldr d0, [src, #\base + 8]
- vstr d1, [dst, #\base + 16]
- vldr d1, [src, #\base + 16]
- vstr d2, [dst, #\base + 24]
- vldr d2, [src, #\base + 24]
- vstr \vreg, [dst, #\base + 32]
- vstr d0, [dst, #\base + 40]
- vldr d0, [src, #\base + 40]
- vstr d1, [dst, #\base + 48]
- vldr d1, [src, #\base + 48]
- vstr d2, [dst, #\base + 56]
- vldr d2, [src, #\base + 56]
- .endm
-#endif
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-def_fn __memcpy_arm p2align=6
-
- mov dst, dstin /* Preserve dstin, we need to return it. */
- cmp count, #64
- bge .Lcpy_not_short
- /* Deal with small copies quickly by dropping straight into the
- exit block. */
-
-.Ltail63unaligned:
-#ifdef USE_NEON
- and tmp1, count, #0x38
- rsb tmp1, tmp1, #(56 - PC_OFFSET + INSN_SIZE)
- add pc, pc, tmp1
- vld1.8 {d0}, [src]! /* 14 words to go. */
- vst1.8 {d0}, [dst]!
- vld1.8 {d0}, [src]! /* 12 words to go. */
- vst1.8 {d0}, [dst]!
- vld1.8 {d0}, [src]! /* 10 words to go. */
- vst1.8 {d0}, [dst]!
- vld1.8 {d0}, [src]! /* 8 words to go. */
- vst1.8 {d0}, [dst]!
- vld1.8 {d0}, [src]! /* 6 words to go. */
- vst1.8 {d0}, [dst]!
- vld1.8 {d0}, [src]! /* 4 words to go. */
- vst1.8 {d0}, [dst]!
- vld1.8 {d0}, [src]! /* 2 words to go. */
- vst1.8 {d0}, [dst]!
-
- tst count, #4
- ldrne tmp1, [src], #4
- strne tmp1, [dst], #4
-#else
- /* Copy up to 15 full words of data. May not be aligned. */
- /* Cannot use VFP for unaligned data. */
- and tmp1, count, #0x3c
- add dst, dst, tmp1
- add src, src, tmp1
- rsb tmp1, tmp1, #(60 - PC_OFFSET/2 + INSN_SIZE/2)
- /* Jump directly into the sequence below at the correct offset. */
- add pc, pc, tmp1, lsl #1
-
- ldr tmp1, [src, #-60] /* 15 words to go. */
- str tmp1, [dst, #-60]
-
- ldr tmp1, [src, #-56] /* 14 words to go. */
- str tmp1, [dst, #-56]
- ldr tmp1, [src, #-52]
- str tmp1, [dst, #-52]
-
- ldr tmp1, [src, #-48] /* 12 words to go. */
- str tmp1, [dst, #-48]
- ldr tmp1, [src, #-44]
- str tmp1, [dst, #-44]
-
- ldr tmp1, [src, #-40] /* 10 words to go. */
- str tmp1, [dst, #-40]
- ldr tmp1, [src, #-36]
- str tmp1, [dst, #-36]
-
- ldr tmp1, [src, #-32] /* 8 words to go. */
- str tmp1, [dst, #-32]
- ldr tmp1, [src, #-28]
- str tmp1, [dst, #-28]
-
- ldr tmp1, [src, #-24] /* 6 words to go. */
- str tmp1, [dst, #-24]
- ldr tmp1, [src, #-20]
- str tmp1, [dst, #-20]
-
- ldr tmp1, [src, #-16] /* 4 words to go. */
- str tmp1, [dst, #-16]
- ldr tmp1, [src, #-12]
- str tmp1, [dst, #-12]
-
- ldr tmp1, [src, #-8] /* 2 words to go. */
- str tmp1, [dst, #-8]
- ldr tmp1, [src, #-4]
- str tmp1, [dst, #-4]
-#endif
-
- lsls count, count, #31
- ldrhcs tmp1, [src], #2
- ldrbne src, [src] /* Src is dead, use as a scratch. */
- strhcs tmp1, [dst], #2
- strbne src, [dst]
- bx lr
-
-.Lcpy_not_short:
- /* At least 64 bytes to copy, but don't know the alignment yet. */
- str tmp2, [sp, #-FRAME_SIZE]!
- and tmp2, src, #7
- and tmp1, dst, #7
- cmp tmp1, tmp2
- bne .Lcpy_notaligned
-
-#ifdef USE_VFP
- /* Magic dust alert! Force VFP on Cortex-A9. Experiments show
- that the FP pipeline is much better at streaming loads and
- stores. This is outside the critical loop. */
- vmov.f32 s0, s0
-#endif
-
- /* SRC and DST have the same mutual 64-bit alignment, but we may
- still need to pre-copy some bytes to get to natural alignment.
- We bring SRC and DST into full 64-bit alignment. */
- lsls tmp2, dst, #29
- beq 1f
- rsbs tmp2, tmp2, #0
- sub count, count, tmp2, lsr #29
- ldrmi tmp1, [src], #4
- strmi tmp1, [dst], #4
- lsls tmp2, tmp2, #2
- ldrhcs tmp1, [src], #2
- ldrbne tmp2, [src], #1
- strhcs tmp1, [dst], #2
- strbne tmp2, [dst], #1
-
-1:
- subs tmp2, count, #64 /* Use tmp2 for count. */
- blt .Ltail63aligned
-
- cmp tmp2, #512
- bge .Lcpy_body_long
-
-.Lcpy_body_medium: /* Count in tmp2. */
-#ifdef USE_VFP
-1:
- vldr d0, [src, #0]
- subs tmp2, tmp2, #64
- vldr d1, [src, #8]
- vstr d0, [dst, #0]
- vldr d0, [src, #16]
- vstr d1, [dst, #8]
- vldr d1, [src, #24]
- vstr d0, [dst, #16]
- vldr d0, [src, #32]
- vstr d1, [dst, #24]
- vldr d1, [src, #40]
- vstr d0, [dst, #32]
- vldr d0, [src, #48]
- vstr d1, [dst, #40]
- vldr d1, [src, #56]
- vstr d0, [dst, #48]
- add src, src, #64
- vstr d1, [dst, #56]
- add dst, dst, #64
- bge 1b
- tst tmp2, #0x3f
- beq .Ldone
-
-.Ltail63aligned: /* Count in tmp2. */
- and tmp1, tmp2, #0x38
- add dst, dst, tmp1
- add src, src, tmp1
- rsb tmp1, tmp1, #(56 - PC_OFFSET + INSN_SIZE)
- add pc, pc, tmp1
-
- vldr d0, [src, #-56] /* 14 words to go. */
- vstr d0, [dst, #-56]
- vldr d0, [src, #-48] /* 12 words to go. */
- vstr d0, [dst, #-48]
- vldr d0, [src, #-40] /* 10 words to go. */
- vstr d0, [dst, #-40]
- vldr d0, [src, #-32] /* 8 words to go. */
- vstr d0, [dst, #-32]
- vldr d0, [src, #-24] /* 6 words to go. */
- vstr d0, [dst, #-24]
- vldr d0, [src, #-16] /* 4 words to go. */
- vstr d0, [dst, #-16]
- vldr d0, [src, #-8] /* 2 words to go. */
- vstr d0, [dst, #-8]
-#else
- sub src, src, #8
- sub dst, dst, #8
-1:
- ldrd A_l, A_h, [src, #8]
- strd A_l, A_h, [dst, #8]
- ldrd A_l, A_h, [src, #16]
- strd A_l, A_h, [dst, #16]
- ldrd A_l, A_h, [src, #24]
- strd A_l, A_h, [dst, #24]
- ldrd A_l, A_h, [src, #32]
- strd A_l, A_h, [dst, #32]
- ldrd A_l, A_h, [src, #40]
- strd A_l, A_h, [dst, #40]
- ldrd A_l, A_h, [src, #48]
- strd A_l, A_h, [dst, #48]
- ldrd A_l, A_h, [src, #56]
- strd A_l, A_h, [dst, #56]
- ldrd A_l, A_h, [src, #64]!
- strd A_l, A_h, [dst, #64]!
- subs tmp2, tmp2, #64
- bge 1b
- tst tmp2, #0x3f
- bne 1f
- ldr tmp2,[sp], #FRAME_SIZE
- bx lr
-1:
- add src, src, #8
- add dst, dst, #8
-
-.Ltail63aligned: /* Count in tmp2. */
- /* Copy up to 7 d-words of data. Similar to Ltail63unaligned, but
- we know that the src and dest are 64-bit aligned so we can use
- LDRD/STRD to improve efficiency. */
- /* TMP2 is now negative, but we don't care about that. The bottom
- six bits still tell us how many bytes are left to copy. */
-
- and tmp1, tmp2, #0x38
- add dst, dst, tmp1
- add src, src, tmp1
- rsb tmp1, tmp1, #(56 - PC_OFFSET + INSN_SIZE)
- add pc, pc, tmp1
- ldrd A_l, A_h, [src, #-56] /* 14 words to go. */
- strd A_l, A_h, [dst, #-56]
- ldrd A_l, A_h, [src, #-48] /* 12 words to go. */
- strd A_l, A_h, [dst, #-48]
- ldrd A_l, A_h, [src, #-40] /* 10 words to go. */
- strd A_l, A_h, [dst, #-40]
- ldrd A_l, A_h, [src, #-32] /* 8 words to go. */
- strd A_l, A_h, [dst, #-32]
- ldrd A_l, A_h, [src, #-24] /* 6 words to go. */
- strd A_l, A_h, [dst, #-24]
- ldrd A_l, A_h, [src, #-16] /* 4 words to go. */
- strd A_l, A_h, [dst, #-16]
- ldrd A_l, A_h, [src, #-8] /* 2 words to go. */
- strd A_l, A_h, [dst, #-8]
-
-#endif
- tst tmp2, #4
- ldrne tmp1, [src], #4
- strne tmp1, [dst], #4
- lsls tmp2, tmp2, #31 /* Count (tmp2) now dead. */
- ldrhcs tmp1, [src], #2
- ldrbne tmp2, [src]
- strhcs tmp1, [dst], #2
- strbne tmp2, [dst]
-
-.Ldone:
- ldr tmp2, [sp], #FRAME_SIZE
- bx lr
-
-.Lcpy_body_long: /* Count in tmp2. */
-
- /* Long copy. We know that there's at least (prefetch_lines * 64)
- bytes to go. */
-#ifdef USE_VFP
- /* Don't use PLD. Instead, read some data in advance of the current
- copy position into a register. This should act like a PLD
- operation but we won't have to repeat the transfer. */
-
- vldr d3, [src, #0]
- vldr d4, [src, #64]
- vldr d5, [src, #128]
- vldr d6, [src, #192]
- vldr d7, [src, #256]
-
- vldr d0, [src, #8]
- vldr d1, [src, #16]
- vldr d2, [src, #24]
- add src, src, #32
-
- subs tmp2, tmp2, #prefetch_lines * 64 * 2
- blt 2f
-1:
- cpy_line_vfp d3, 0
- cpy_line_vfp d4, 64
- cpy_line_vfp d5, 128
- add dst, dst, #3 * 64
- add src, src, #3 * 64
- cpy_line_vfp d6, 0
- cpy_line_vfp d7, 64
- add dst, dst, #2 * 64
- add src, src, #2 * 64
- subs tmp2, tmp2, #prefetch_lines * 64
- bge 1b
-
-2:
- cpy_tail_vfp d3, 0
- cpy_tail_vfp d4, 64
- cpy_tail_vfp d5, 128
- add src, src, #3 * 64
- add dst, dst, #3 * 64
- cpy_tail_vfp d6, 0
- vstr d7, [dst, #64]
- vldr d7, [src, #64]
- vstr d0, [dst, #64 + 8]
- vldr d0, [src, #64 + 8]
- vstr d1, [dst, #64 + 16]
- vldr d1, [src, #64 + 16]
- vstr d2, [dst, #64 + 24]
- vldr d2, [src, #64 + 24]
- vstr d7, [dst, #64 + 32]
- add src, src, #96
- vstr d0, [dst, #64 + 40]
- vstr d1, [dst, #64 + 48]
- vstr d2, [dst, #64 + 56]
- add dst, dst, #128
- add tmp2, tmp2, #prefetch_lines * 64
- b .Lcpy_body_medium
-#else
- /* Long copy. Use an SMS style loop to maximize the I/O
- bandwidth of the core. We don't have enough spare registers
- to synthesise prefetching, so use PLD operations. */
- /* Pre-bias src and dst. */
- sub src, src, #8
- sub dst, dst, #8
- pld [src, #8]
- pld [src, #72]
- subs tmp2, tmp2, #64
- pld [src, #136]
- ldrd A_l, A_h, [src, #8]
- strd B_l, B_h, [sp, #8]
- ldrd B_l, B_h, [src, #16]
- strd C_l, C_h, [sp, #16]
- ldrd C_l, C_h, [src, #24]
- strd D_l, D_h, [sp, #24]
- pld [src, #200]
- ldrd D_l, D_h, [src, #32]!
- b 1f
- .p2align 6
-2:
- pld [src, #232]
- strd A_l, A_h, [dst, #40]
- ldrd A_l, A_h, [src, #40]
- strd B_l, B_h, [dst, #48]
- ldrd B_l, B_h, [src, #48]
- strd C_l, C_h, [dst, #56]
- ldrd C_l, C_h, [src, #56]
- strd D_l, D_h, [dst, #64]!
- ldrd D_l, D_h, [src, #64]!
- subs tmp2, tmp2, #64
-1:
- strd A_l, A_h, [dst, #8]
- ldrd A_l, A_h, [src, #8]
- strd B_l, B_h, [dst, #16]
- ldrd B_l, B_h, [src, #16]
- strd C_l, C_h, [dst, #24]
- ldrd C_l, C_h, [src, #24]
- strd D_l, D_h, [dst, #32]
- ldrd D_l, D_h, [src, #32]
- bcs 2b
- /* Save the remaining bytes and restore the callee-saved regs. */
- strd A_l, A_h, [dst, #40]
- add src, src, #40
- strd B_l, B_h, [dst, #48]
- ldrd B_l, B_h, [sp, #8]
- strd C_l, C_h, [dst, #56]
- ldrd C_l, C_h, [sp, #16]
- strd D_l, D_h, [dst, #64]
- ldrd D_l, D_h, [sp, #24]
- add dst, dst, #72
- tst tmp2, #0x3f
- bne .Ltail63aligned
- ldr tmp2, [sp], #FRAME_SIZE
- bx lr
-#endif
-
-.Lcpy_notaligned:
- pld [src]
- pld [src, #64]
- /* There's at least 64 bytes to copy, but there is no mutual
- alignment. */
- /* Bring DST to 64-bit alignment. */
- lsls tmp2, dst, #29
- pld [src, #(2 * 64)]
- beq 1f
- rsbs tmp2, tmp2, #0
- sub count, count, tmp2, lsr #29
- ldrmi tmp1, [src], #4
- strmi tmp1, [dst], #4
- lsls tmp2, tmp2, #2
- ldrbne tmp1, [src], #1
- ldrhcs tmp2, [src], #2
- strbne tmp1, [dst], #1
- strhcs tmp2, [dst], #2
-1:
- pld [src, #(3 * 64)]
- subs count, count, #64
- ldrmi tmp2, [sp], #FRAME_SIZE
- bmi .Ltail63unaligned
- pld [src, #(4 * 64)]
-
-#ifdef USE_NEON
- vld1.8 {d0-d3}, [src]!
- vld1.8 {d4-d7}, [src]!
- subs count, count, #64
- bmi 2f
-1:
- pld [src, #(4 * 64)]
- vst1.8 {d0-d3}, [ALIGN (dst, 64)]!
- vld1.8 {d0-d3}, [src]!
- vst1.8 {d4-d7}, [ALIGN (dst, 64)]!
- vld1.8 {d4-d7}, [src]!
- subs count, count, #64
- bpl 1b
-2:
- vst1.8 {d0-d3}, [ALIGN (dst, 64)]!
- vst1.8 {d4-d7}, [ALIGN (dst, 64)]!
- ands count, count, #0x3f
-#else
- /* Use an SMS style loop to maximize the I/O bandwidth. */
- sub src, src, #4
- sub dst, dst, #8
- subs tmp2, count, #64 /* Use tmp2 for count. */
- ldr A_l, [src, #4]
- ldr A_h, [src, #8]
- strd B_l, B_h, [sp, #8]
- ldr B_l, [src, #12]
- ldr B_h, [src, #16]
- strd C_l, C_h, [sp, #16]
- ldr C_l, [src, #20]
- ldr C_h, [src, #24]
- strd D_l, D_h, [sp, #24]
- ldr D_l, [src, #28]
- ldr D_h, [src, #32]!
- b 1f
- .p2align 6
-2:
- pld [src, #(5 * 64) - (32 - 4)]
- strd A_l, A_h, [dst, #40]
- ldr A_l, [src, #36]
- ldr A_h, [src, #40]
- strd B_l, B_h, [dst, #48]
- ldr B_l, [src, #44]
- ldr B_h, [src, #48]
- strd C_l, C_h, [dst, #56]
- ldr C_l, [src, #52]
- ldr C_h, [src, #56]
- strd D_l, D_h, [dst, #64]!
- ldr D_l, [src, #60]
- ldr D_h, [src, #64]!
- subs tmp2, tmp2, #64
-1:
- strd A_l, A_h, [dst, #8]
- ldr A_l, [src, #4]
- ldr A_h, [src, #8]
- strd B_l, B_h, [dst, #16]
- ldr B_l, [src, #12]
- ldr B_h, [src, #16]
- strd C_l, C_h, [dst, #24]
- ldr C_l, [src, #20]
- ldr C_h, [src, #24]
- strd D_l, D_h, [dst, #32]
- ldr D_l, [src, #28]
- ldr D_h, [src, #32]
- bcs 2b
-
- /* Save the remaining bytes and restore the callee-saved regs. */
- strd A_l, A_h, [dst, #40]
- add src, src, #36
- strd B_l, B_h, [dst, #48]
- ldrd B_l, B_h, [sp, #8]
- strd C_l, C_h, [dst, #56]
- ldrd C_l, C_h, [sp, #16]
- strd D_l, D_h, [dst, #64]
- ldrd D_l, D_h, [sp, #24]
- add dst, dst, #72
- ands count, tmp2, #0x3f
-#endif
- ldr tmp2, [sp], #FRAME_SIZE
- bne .Ltail63unaligned
- bx lr
-
- .size __memcpy_arm, . - __memcpy_arm
diff --git a/string/arm/memset.S b/string/arm/memset.S
deleted file mode 100644
index 3ee5238..0000000
--- a/string/arm/memset.S
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * memset - fill memory with a constant
- *
- * Copyright (c) 2010, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/*
- Written by Dave Gilbert <david.gilbert@linaro.org>
-
- This memset routine is optimised on a Cortex-A9 and should work on
- all ARMv7 processors.
-
- */
-
- .syntax unified
- .arch armv7-a
-
-@ 2011-08-30 david.gilbert@linaro.org
-@ Extracted from local git 2f11b436
-
-@ this lets us check a flag in a 00/ff byte easily in either endianness
-#ifdef __ARMEB__
-#define CHARTSTMASK(c) 1<<(31-(c*8))
-#else
-#define CHARTSTMASK(c) 1<<(c*8)
-#endif
- .text
- .thumb
-
-@ ---------------------------------------------------------------------------
- .thumb_func
- .align 2
- .p2align 4,,15
- .global __memset_arm
- .type __memset_arm,%function
-__memset_arm:
- @ r0 = address
- @ r1 = character
- @ r2 = count
- @ returns original address in r0
-
- mov r3, r0 @ Leave r0 alone
- cbz r2, 10f @ Exit if 0 length
-
- tst r0, #7
- beq 2f @ Already aligned
-
- @ Ok, so we're misaligned here
-1:
- strb r1, [r3], #1
- subs r2,r2,#1
- tst r3, #7
- cbz r2, 10f @ Exit if we hit the end
- bne 1b @ go round again if still misaligned
-
-2:
- @ OK, so we're aligned
- push {r4,r5,r6,r7}
- bics r4, r2, #15 @ if less than 16 bytes then need to finish it off
- beq 5f
-
-3:
- @ POSIX says that ch is cast to an unsigned char. A uxtb is one
- @ byte and takes two cycles, where an AND is four bytes but one
- @ cycle.
- and r1, #0xFF
- orr r1, r1, r1, lsl#8 @ Same character into all bytes
- orr r1, r1, r1, lsl#16
- mov r5,r1
- mov r6,r1
- mov r7,r1
-
-4:
- subs r4,r4,#16
- stmia r3!,{r1,r5,r6,r7}
- bne 4b
- and r2,r2,#15
-
- @ At this point we're still aligned and we have upto align-1 bytes left to right
- @ we can avoid some of the byte-at-a time now by testing for some big chunks
- tst r2,#8
- itt ne
- subne r2,r2,#8
- stmiane r3!,{r1,r5}
-
-5:
- pop {r4,r5,r6,r7}
- cbz r2, 10f
-
- @ Got to do any last < alignment bytes
-6:
- subs r2,r2,#1
- strb r1,[r3],#1
- bne 6b
-
-10:
- bx lr @ goodbye
- .size __memset_arm, . - __memset_arm
diff --git a/string/arm/strcmp-armv6m.S b/string/arm/strcmp-armv6m.S
deleted file mode 100644
index 5ea06c9..0000000
--- a/string/arm/strcmp-armv6m.S
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * strcmp for ARMv6-M (optimized for performance, not size)
- *
- * Copyright (c) 2014-2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
- .thumb_func
- .syntax unified
- .arch armv6-m
-
- .macro DoSub n, label
- subs r0, r0, r1
-#ifdef __ARM_BIG_ENDIAN
- lsrs r1, r4, \n
-#else
- lsls r1, r4, \n
-#endif
- orrs r1, r0
- bne \label
- .endm
-
- .macro Byte_Test n, label
- lsrs r0, r2, \n
- lsrs r1, r3, \n
- DoSub \n, \label
- .endm
-
- .text
- .p2align 0
- .global __strcmp_armv6m
- .type __strcmp_armv6m, %function
-__strcmp_armv6m:
- .cfi_startproc
- mov r2, r0
- push {r4, r5, r6, lr}
- orrs r2, r1
- lsls r2, r2, #30
- bne 6f
- ldr r5, =0x01010101
- lsls r6, r5, #7
-1:
- ldmia r0!, {r2}
- ldmia r1!, {r3}
- subs r4, r2, r5
- bics r4, r2
- ands r4, r6
- beq 3f
-
-#ifdef __ARM_BIG_ENDIAN
- Byte_Test #24, 4f
- Byte_Test #16, 4f
- Byte_Test #8, 4f
-
- b 7f
-3:
- cmp r2, r3
- beq 1b
- cmp r2, r3
-#else
- uxtb r0, r2
- uxtb r1, r3
- DoSub #24, 2f
-
- uxth r0, r2
- uxth r1, r3
- DoSub #16, 2f
-
- lsls r0, r2, #8
- lsls r1, r3, #8
- lsrs r0, r0, #8
- lsrs r1, r1, #8
- DoSub #8, 2f
-
- lsrs r0, r2, #24
- lsrs r1, r3, #24
- subs r0, r0, r1
-2:
- pop {r4, r5, r6, pc}
-
-3:
- cmp r2, r3
- beq 1b
- rev r0, r2
- rev r1, r3
- cmp r0, r1
-#endif
-
- bls 5f
- movs r0, #1
-4:
- pop {r4, r5, r6, pc}
-5:
- movs r0, #0
- mvns r0, r0
- pop {r4, r5, r6, pc}
-6:
- ldrb r2, [r0, #0]
- ldrb r3, [r1, #0]
- adds r0, #1
- adds r1, #1
- cmp r2, #0
- beq 7f
- cmp r2, r3
- bne 7f
- ldrb r2, [r0, #0]
- ldrb r3, [r1, #0]
- adds r0, #1
- adds r1, #1
- cmp r2, #0
- beq 7f
- cmp r2, r3
- beq 6b
-7:
- subs r0, r2, r3
- pop {r4, r5, r6, pc}
- .cfi_endproc
- .size __strcmp_armv6m, . - __strcmp_armv6m
diff --git a/string/arm/strcmp.S b/string/arm/strcmp.S
deleted file mode 100644
index fb9cae3..0000000
--- a/string/arm/strcmp.S
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * strcmp for ARMv7
- *
- * Copyright (c) 2012-2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* Implementation of strcmp for ARMv7 when DSP instructions are
- available. Use ldrd to support wider loads, provided the data
- is sufficiently aligned. Use saturating arithmetic to optimize
- the compares. */
-
-/* Build Options:
- STRCMP_NO_PRECHECK: Don't run a quick pre-check of the first
- byte in the string. If comparing completely random strings
- the pre-check will save time, since there is a very high
- probability of a mismatch in the first character: we save
- significant overhead if this is the common case. However,
- if strings are likely to be identical (eg because we're
- verifying a hit in a hash table), then this check is largely
- redundant. */
-
-#define STRCMP_NO_PRECHECK 0
-
- /* This version uses Thumb-2 code. */
- .thumb
- .syntax unified
-
-#ifdef __ARM_BIG_ENDIAN
-#define S2LO lsl
-#define S2LOEQ lsleq
-#define S2HI lsr
-#define MSB 0x000000ff
-#define LSB 0xff000000
-#define BYTE0_OFFSET 24
-#define BYTE1_OFFSET 16
-#define BYTE2_OFFSET 8
-#define BYTE3_OFFSET 0
-#else /* not __ARM_BIG_ENDIAN */
-#define S2LO lsr
-#define S2LOEQ lsreq
-#define S2HI lsl
-#define BYTE0_OFFSET 0
-#define BYTE1_OFFSET 8
-#define BYTE2_OFFSET 16
-#define BYTE3_OFFSET 24
-#define MSB 0xff000000
-#define LSB 0x000000ff
-#endif /* not __ARM_BIG_ENDIAN */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-/* Parameters and result. */
-#define src1 r0
-#define src2 r1
-#define result r0 /* Overlaps src1. */
-
-/* Internal variables. */
-#define tmp1 r4
-#define tmp2 r5
-#define const_m1 r12
-
-/* Additional internal variables for 64-bit aligned data. */
-#define data1a r2
-#define data1b r3
-#define data2a r6
-#define data2b r7
-#define syndrome_a tmp1
-#define syndrome_b tmp2
-
-/* Additional internal variables for 32-bit aligned data. */
-#define data1 r2
-#define data2 r3
-#define syndrome tmp2
-
-
- /* Macro to compute and return the result value for word-aligned
- cases. */
- .macro strcmp_epilogue_aligned synd d1 d2 restore_r6
-#ifdef __ARM_BIG_ENDIAN
- /* If data1 contains a zero byte, then syndrome will contain a 1 in
- bit 7 of that byte. Otherwise, the highest set bit in the
- syndrome will highlight the first different bit. It is therefore
- sufficient to extract the eight bits starting with the syndrome
- bit. */
- clz tmp1, \synd
- lsl r1, \d2, tmp1
- .if \restore_r6
- ldrd r6, r7, [sp, #8]
- .endif
- .cfi_restore 6
- .cfi_restore 7
- lsl \d1, \d1, tmp1
- .cfi_remember_state
- lsr result, \d1, #24
- ldrd r4, r5, [sp], #16
- .cfi_restore 4
- .cfi_restore 5
- sub result, result, r1, lsr #24
- bx lr
-#else
- /* To use the big-endian trick we'd have to reverse all three words.
- that's slower than this approach. */
- rev \synd, \synd
- clz tmp1, \synd
- bic tmp1, tmp1, #7
- lsr r1, \d2, tmp1
- .cfi_remember_state
- .if \restore_r6
- ldrd r6, r7, [sp, #8]
- .endif
- .cfi_restore 6
- .cfi_restore 7
- lsr \d1, \d1, tmp1
- and result, \d1, #255
- and r1, r1, #255
- ldrd r4, r5, [sp], #16
- .cfi_restore 4
- .cfi_restore 5
- sub result, result, r1
-
- bx lr
-#endif
- .endm
-
- .text
- .p2align 5
-.Lstrcmp_start_addr:
-#if STRCMP_NO_PRECHECK == 0
-.Lfastpath_exit:
- sub r0, r2, r3
- bx lr
- nop
-#endif
-def_fn __strcmp_arm
-#if STRCMP_NO_PRECHECK == 0
- ldrb r2, [src1]
- ldrb r3, [src2]
- cmp r2, #1
- it cs
- cmpcs r2, r3
- bne .Lfastpath_exit
-#endif
- .cfi_startproc
- strd r4, r5, [sp, #-16]!
- .cfi_def_cfa_offset 16
- .cfi_offset 4, -16
- .cfi_offset 5, -12
- orr tmp1, src1, src2
- strd r6, r7, [sp, #8]
- .cfi_offset 6, -8
- .cfi_offset 7, -4
- mvn const_m1, #0
- lsl r2, tmp1, #29
- cbz r2, .Lloop_aligned8
-
-.Lnot_aligned:
- eor tmp1, src1, src2
- tst tmp1, #7
- bne .Lmisaligned8
-
- /* Deal with mutual misalignment by aligning downwards and then
- masking off the unwanted loaded data to prevent a difference. */
- and tmp1, src1, #7
- bic src1, src1, #7
- and tmp2, tmp1, #3
- bic src2, src2, #7
- lsl tmp2, tmp2, #3 /* Bytes -> bits. */
- ldrd data1a, data1b, [src1], #16
- tst tmp1, #4
- ldrd data2a, data2b, [src2], #16
- /* In thumb code we can't use MVN with a register shift, but
- we do have ORN. */
- S2HI tmp1, const_m1, tmp2
- orn data1a, data1a, tmp1
- orn data2a, data2a, tmp1
- beq .Lstart_realigned8
- orn data1b, data1b, tmp1
- mov data1a, const_m1
- orn data2b, data2b, tmp1
- mov data2a, const_m1
- b .Lstart_realigned8
-
- /* Unwind the inner loop by a factor of 2, giving 16 bytes per
- pass. */
- .p2align 5,,12 /* Don't start in the tail bytes of a cache line. */
- .p2align 2 /* Always word aligned. */
-.Lloop_aligned8:
- ldrd data1a, data1b, [src1], #16
- ldrd data2a, data2b, [src2], #16
-.Lstart_realigned8:
- uadd8 syndrome_b, data1a, const_m1 /* Only want GE bits, */
- eor syndrome_a, data1a, data2a
- sel syndrome_a, syndrome_a, const_m1
- cbnz syndrome_a, .Ldiff_in_a
- uadd8 syndrome_b, data1b, const_m1 /* Only want GE bits. */
- eor syndrome_b, data1b, data2b
- sel syndrome_b, syndrome_b, const_m1
- cbnz syndrome_b, .Ldiff_in_b
-
- ldrd data1a, data1b, [src1, #-8]
- ldrd data2a, data2b, [src2, #-8]
- uadd8 syndrome_b, data1a, const_m1 /* Only want GE bits, */
- eor syndrome_a, data1a, data2a
- sel syndrome_a, syndrome_a, const_m1
- uadd8 syndrome_b, data1b, const_m1 /* Only want GE bits. */
- eor syndrome_b, data1b, data2b
- sel syndrome_b, syndrome_b, const_m1
- /* Can't use CBZ for backwards branch. */
- orrs syndrome_b, syndrome_b, syndrome_a /* Only need if s_a == 0 */
- beq .Lloop_aligned8
-
-.Ldiff_found:
- cbnz syndrome_a, .Ldiff_in_a
-
-.Ldiff_in_b:
- strcmp_epilogue_aligned syndrome_b, data1b, data2b 1
-
-.Ldiff_in_a:
- .cfi_restore_state
- strcmp_epilogue_aligned syndrome_a, data1a, data2a 1
-
- .cfi_restore_state
-.Lmisaligned8:
- tst tmp1, #3
- bne .Lmisaligned4
- ands tmp1, src1, #3
- bne .Lmutual_align4
-
- /* Unrolled by a factor of 2, to reduce the number of post-increment
- operations. */
-.Lloop_aligned4:
- ldr data1, [src1], #8
- ldr data2, [src2], #8
-.Lstart_realigned4:
- uadd8 syndrome, data1, const_m1 /* Only need GE bits. */
- eor syndrome, data1, data2
- sel syndrome, syndrome, const_m1
- cbnz syndrome, .Laligned4_done
- ldr data1, [src1, #-4]
- ldr data2, [src2, #-4]
- uadd8 syndrome, data1, const_m1
- eor syndrome, data1, data2
- sel syndrome, syndrome, const_m1
- cmp syndrome, #0
- beq .Lloop_aligned4
-
-.Laligned4_done:
- strcmp_epilogue_aligned syndrome, data1, data2, 0
-
-.Lmutual_align4:
- .cfi_restore_state
- /* Deal with mutual misalignment by aligning downwards and then
- masking off the unwanted loaded data to prevent a difference. */
- lsl tmp1, tmp1, #3 /* Bytes -> bits. */
- bic src1, src1, #3
- ldr data1, [src1], #8
- bic src2, src2, #3
- ldr data2, [src2], #8
-
- /* In thumb code we can't use MVN with a register shift, but
- we do have ORN. */
- S2HI tmp1, const_m1, tmp1
- orn data1, data1, tmp1
- orn data2, data2, tmp1
- b .Lstart_realigned4
-
-.Lmisaligned4:
- ands tmp1, src1, #3
- beq .Lsrc1_aligned
- sub src2, src2, tmp1
- bic src1, src1, #3
- lsls tmp1, tmp1, #31
- ldr data1, [src1], #4
- beq .Laligned_m2
- bcs .Laligned_m1
-
-#if STRCMP_NO_PRECHECK == 1
- ldrb data2, [src2, #1]
- uxtb tmp1, data1, ror #BYTE1_OFFSET
- subs tmp1, tmp1, data2
- bne .Lmisaligned_exit
- cbz data2, .Lmisaligned_exit
-
-.Laligned_m2:
- ldrb data2, [src2, #2]
- uxtb tmp1, data1, ror #BYTE2_OFFSET
- subs tmp1, tmp1, data2
- bne .Lmisaligned_exit
- cbz data2, .Lmisaligned_exit
-
-.Laligned_m1:
- ldrb data2, [src2, #3]
- uxtb tmp1, data1, ror #BYTE3_OFFSET
- subs tmp1, tmp1, data2
- bne .Lmisaligned_exit
- add src2, src2, #4
- cbnz data2, .Lsrc1_aligned
-#else /* STRCMP_NO_PRECHECK */
- /* If we've done the pre-check, then we don't need to check the
- first byte again here. */
- ldrb data2, [src2, #2]
- uxtb tmp1, data1, ror #BYTE2_OFFSET
- subs tmp1, tmp1, data2
- bne .Lmisaligned_exit
- cbz data2, .Lmisaligned_exit
-
-.Laligned_m2:
- ldrb data2, [src2, #3]
- uxtb tmp1, data1, ror #BYTE3_OFFSET
- subs tmp1, tmp1, data2
- bne .Lmisaligned_exit
- cbnz data2, .Laligned_m1
-#endif
-
-.Lmisaligned_exit:
- .cfi_remember_state
- mov result, tmp1
- ldr r4, [sp], #16
- .cfi_restore 4
- bx lr
-
-#if STRCMP_NO_PRECHECK == 0
-.Laligned_m1:
- add src2, src2, #4
-#endif
-.Lsrc1_aligned:
- .cfi_restore_state
- /* src1 is word aligned, but src2 has no common alignment
- with it. */
- ldr data1, [src1], #4
- lsls tmp1, src2, #31 /* C=src2[1], Z=src2[0]. */
-
- bic src2, src2, #3
- ldr data2, [src2], #4
- bhi .Loverlap1 /* C=1, Z=0 => src2[1:0] = 0b11. */
- bcs .Loverlap2 /* C=1, Z=1 => src2[1:0] = 0b10. */
-
- /* (overlap3) C=0, Z=0 => src2[1:0] = 0b01. */
-.Loverlap3:
- bic tmp1, data1, #MSB
- uadd8 syndrome, data1, const_m1
- eors syndrome, tmp1, data2, S2LO #8
- sel syndrome, syndrome, const_m1
- bne 4f
- cbnz syndrome, 5f
- ldr data2, [src2], #4
- eor tmp1, tmp1, data1
- cmp tmp1, data2, S2HI #24
- bne 6f
- ldr data1, [src1], #4
- b .Loverlap3
-4:
- S2LO data2, data2, #8
- b .Lstrcmp_tail
-
-5:
- bics syndrome, syndrome, #MSB
- bne .Lstrcmp_done_equal
-
- /* We can only get here if the MSB of data1 contains 0, so
- fast-path the exit. */
- ldrb result, [src2]
- .cfi_remember_state
- ldrd r4, r5, [sp], #16
- .cfi_restore 4
- .cfi_restore 5
- /* R6/7 Not used in this sequence. */
- .cfi_restore 6
- .cfi_restore 7
- neg result, result
- bx lr
-
-6:
- .cfi_restore_state
- S2LO data1, data1, #24
- and data2, data2, #LSB
- b .Lstrcmp_tail
-
- .p2align 5,,12 /* Ensure at least 3 instructions in cache line. */
-.Loverlap2:
- and tmp1, data1, const_m1, S2LO #16
- uadd8 syndrome, data1, const_m1
- eors syndrome, tmp1, data2, S2LO #16
- sel syndrome, syndrome, const_m1
- bne 4f
- cbnz syndrome, 5f
- ldr data2, [src2], #4
- eor tmp1, tmp1, data1
- cmp tmp1, data2, S2HI #16
- bne 6f
- ldr data1, [src1], #4
- b .Loverlap2
-4:
- S2LO data2, data2, #16
- b .Lstrcmp_tail
-5:
- ands syndrome, syndrome, const_m1, S2LO #16
- bne .Lstrcmp_done_equal
-
- ldrh data2, [src2]
- S2LO data1, data1, #16
-#ifdef __ARM_BIG_ENDIAN
- lsl data2, data2, #16
-#endif
- b .Lstrcmp_tail
-
-6:
- S2LO data1, data1, #16
- and data2, data2, const_m1, S2LO #16
- b .Lstrcmp_tail
-
- .p2align 5,,12 /* Ensure at least 3 instructions in cache line. */
-.Loverlap1:
- and tmp1, data1, #LSB
- uadd8 syndrome, data1, const_m1
- eors syndrome, tmp1, data2, S2LO #24
- sel syndrome, syndrome, const_m1
- bne 4f
- cbnz syndrome, 5f
- ldr data2, [src2], #4
- eor tmp1, tmp1, data1
- cmp tmp1, data2, S2HI #8
- bne 6f
- ldr data1, [src1], #4
- b .Loverlap1
-4:
- S2LO data2, data2, #24
- b .Lstrcmp_tail
-5:
- tst syndrome, #LSB
- bne .Lstrcmp_done_equal
- ldr data2, [src2]
-6:
- S2LO data1, data1, #8
- bic data2, data2, #MSB
- b .Lstrcmp_tail
-
-.Lstrcmp_done_equal:
- mov result, #0
- .cfi_remember_state
- ldrd r4, r5, [sp], #16
- .cfi_restore 4
- .cfi_restore 5
- /* R6/7 not used in this sequence. */
- .cfi_restore 6
- .cfi_restore 7
- bx lr
-
-.Lstrcmp_tail:
- .cfi_restore_state
-#ifndef __ARM_BIG_ENDIAN
- rev data1, data1
- rev data2, data2
- /* Now everything looks big-endian... */
-#endif
- uadd8 tmp1, data1, const_m1
- eor tmp1, data1, data2
- sel syndrome, tmp1, const_m1
- clz tmp1, syndrome
- lsl data1, data1, tmp1
- lsl data2, data2, tmp1
- lsr result, data1, #24
- ldrd r4, r5, [sp], #16
- .cfi_restore 4
- .cfi_restore 5
- /* R6/7 not used in this sequence. */
- .cfi_restore 6
- .cfi_restore 7
- sub result, result, data2, lsr #24
- bx lr
- .cfi_endproc
- .size __strcmp, . - .Lstrcmp_start_addr
diff --git a/string/arm/strcpy.c b/string/arm/strcpy.c
deleted file mode 100644
index 48ebbe8..0000000
--- a/string/arm/strcpy.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * strcpy
- *
- * Copyright (c) 2008-2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/* For GLIBC:
-#include <string.h>
-#include <memcopy.h>
-
-#undef strcmp
-*/
-
-#ifdef __thumb2__
-#define magic1(REG) "#0x01010101"
-#define magic2(REG) "#0x80808080"
-#else
-#define magic1(REG) #REG
-#define magic2(REG) #REG ", lsl #7"
-#endif
-
-char* __attribute__((naked))
-__strcpy_arm (char* dst, const char* src)
-{
- __asm__ (
- "pld [r1, #0]\n\t"
- "eor r2, r0, r1\n\t"
- "mov ip, r0\n\t"
- "tst r2, #3\n\t"
- "bne 4f\n\t"
- "tst r1, #3\n\t"
- "bne 3f\n"
- "5:\n\t"
-# ifndef __thumb2__
- "str r5, [sp, #-4]!\n\t"
- "mov r5, #0x01\n\t"
- "orr r5, r5, r5, lsl #8\n\t"
- "orr r5, r5, r5, lsl #16\n\t"
-# endif
-
- "str r4, [sp, #-4]!\n\t"
- "tst r1, #4\n\t"
- "ldr r3, [r1], #4\n\t"
- "beq 2f\n\t"
- "sub r2, r3, "magic1(r5)"\n\t"
- "bics r2, r2, r3\n\t"
- "tst r2, "magic2(r5)"\n\t"
- "itt eq\n\t"
- "streq r3, [ip], #4\n\t"
- "ldreq r3, [r1], #4\n"
- "bne 1f\n\t"
- /* Inner loop. We now know that r1 is 64-bit aligned, so we
- can safely fetch up to two words. This allows us to avoid
- load stalls. */
- ".p2align 2\n"
- "2:\n\t"
- "pld [r1, #8]\n\t"
- "ldr r4, [r1], #4\n\t"
- "sub r2, r3, "magic1(r5)"\n\t"
- "bics r2, r2, r3\n\t"
- "tst r2, "magic2(r5)"\n\t"
- "sub r2, r4, "magic1(r5)"\n\t"
- "bne 1f\n\t"
- "str r3, [ip], #4\n\t"
- "bics r2, r2, r4\n\t"
- "tst r2, "magic2(r5)"\n\t"
- "itt eq\n\t"
- "ldreq r3, [r1], #4\n\t"
- "streq r4, [ip], #4\n\t"
- "beq 2b\n\t"
- "mov r3, r4\n"
- "1:\n\t"
-# ifdef __ARMEB__
- "rors r3, r3, #24\n\t"
-# endif
- "strb r3, [ip], #1\n\t"
- "tst r3, #0xff\n\t"
-# ifdef __ARMEL__
- "ror r3, r3, #8\n\t"
-# endif
- "bne 1b\n\t"
- "ldr r4, [sp], #4\n\t"
-# ifndef __thumb2__
- "ldr r5, [sp], #4\n\t"
-# endif
- "BX LR\n"
-
- /* Strings have the same offset from word alignment, but it's
- not zero. */
- "3:\n\t"
- "tst r1, #1\n\t"
- "beq 1f\n\t"
- "ldrb r2, [r1], #1\n\t"
- "strb r2, [ip], #1\n\t"
- "cmp r2, #0\n\t"
- "it eq\n"
- "BXEQ LR\n"
- "1:\n\t"
- "tst r1, #2\n\t"
- "beq 5b\n\t"
- "ldrh r2, [r1], #2\n\t"
-# ifdef __ARMEB__
- "tst r2, #0xff00\n\t"
- "iteet ne\n\t"
- "strneh r2, [ip], #2\n\t"
- "lsreq r2, r2, #8\n\t"
- "streqb r2, [ip]\n\t"
- "tstne r2, #0xff\n\t"
-# else
- "tst r2, #0xff\n\t"
- "itet ne\n\t"
- "strneh r2, [ip], #2\n\t"
- "streqb r2, [ip]\n\t"
- "tstne r2, #0xff00\n\t"
-# endif
- "bne 5b\n\t"
- "BX LR\n"
-
- /* src and dst do not have a common word-alignement. Fall back to
- byte copying. */
- "4:\n\t"
- "ldrb r2, [r1], #1\n\t"
- "strb r2, [ip], #1\n\t"
- "cmp r2, #0\n\t"
- "bne 4b\n\t"
- "BX LR");
-}
-/* For GLIBC: libc_hidden_builtin_def (strcpy) */
diff --git a/string/arm/strlen-armv6t2.S b/string/arm/strlen-armv6t2.S
deleted file mode 100644
index 279ec87..0000000
--- a/string/arm/strlen-armv6t2.S
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * strlen - calculate the length of a string
- *
- * Copyright (c) 2010, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-/*
- Assumes:
- ARMv6T2, AArch32
-
- */
-
- .macro def_fn f p2align=0
- .text
- .p2align \p2align
- .global \f
- .type \f, %function
-\f:
- .endm
-
-#ifdef __ARMEB__
-#define S2LO lsl
-#define S2HI lsr
-#else
-#define S2LO lsr
-#define S2HI lsl
-#endif
-
- /* This code requires Thumb. */
- .thumb
- .syntax unified
-
-/* Parameters and result. */
-#define srcin r0
-#define result r0
-
-/* Internal variables. */
-#define src r1
-#define data1a r2
-#define data1b r3
-#define const_m1 r12
-#define const_0 r4
-#define tmp1 r4 /* Overlaps const_0 */
-#define tmp2 r5
-
-def_fn __strlen_armv6t2 p2align=6
- pld [srcin, #0]
- strd r4, r5, [sp, #-8]!
- bic src, srcin, #7
- mvn const_m1, #0
- ands tmp1, srcin, #7 /* (8 - bytes) to alignment. */
- pld [src, #32]
- bne.w .Lmisaligned8
- mov const_0, #0
- mov result, #-8
-.Lloop_aligned:
- /* Bytes 0-7. */
- ldrd data1a, data1b, [src]
- pld [src, #64]
- add result, result, #8
-.Lstart_realigned:
- uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
- sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
- uadd8 data1b, data1b, const_m1
- sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
- cbnz data1b, .Lnull_found
-
- /* Bytes 8-15. */
- ldrd data1a, data1b, [src, #8]
- uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
- add result, result, #8
- sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
- uadd8 data1b, data1b, const_m1
- sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
- cbnz data1b, .Lnull_found
-
- /* Bytes 16-23. */
- ldrd data1a, data1b, [src, #16]
- uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
- add result, result, #8
- sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
- uadd8 data1b, data1b, const_m1
- sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
- cbnz data1b, .Lnull_found
-
- /* Bytes 24-31. */
- ldrd data1a, data1b, [src, #24]
- add src, src, #32
- uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
- add result, result, #8
- sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
- uadd8 data1b, data1b, const_m1
- sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
- cmp data1b, #0
- beq .Lloop_aligned
-
-.Lnull_found:
- cmp data1a, #0
- itt eq
- addeq result, result, #4
- moveq data1a, data1b
-#ifndef __ARMEB__
- rev data1a, data1a
-#endif
- clz data1a, data1a
- ldrd r4, r5, [sp], #8
- add result, result, data1a, lsr #3 /* Bits -> Bytes. */
- bx lr
-
-.Lmisaligned8:
- ldrd data1a, data1b, [src]
- and tmp2, tmp1, #3
- rsb result, tmp1, #0
- lsl tmp2, tmp2, #3 /* Bytes -> bits. */
- tst tmp1, #4
- pld [src, #64]
- S2HI tmp2, const_m1, tmp2
- orn data1a, data1a, tmp2
- itt ne
- ornne data1b, data1b, tmp2
- movne data1a, const_m1
- mov const_0, #0
- b .Lstart_realigned
- .size __strlen_armv6t2, . - __strlen_armv6t2
diff --git a/string/asmdefs.h b/string/asmdefs.h
deleted file mode 100644
index 7a5bf6b..0000000
--- a/string/asmdefs.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Macros for asm code.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#define ENTRY(name) \
- .global name; \
- .type name,%function; \
- .align 4; \
- name: \
- .cfi_startproc;
-
-#define END(name) \
- .cfi_endproc; \
- .size name, .-name;
diff --git a/string/include/stringlib.h b/string/include/stringlib.h
deleted file mode 100644
index 96647cf..0000000
--- a/string/include/stringlib.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Public API.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stddef.h>
-
-/* restrict is not needed, but kept for documenting the interface contract. */
-#ifndef __restrict
-# define __restrict
-#endif
-
-#if __aarch64__
-void *__memcpy_bytewise (void *__restrict, const void *__restrict, size_t);
-void *__memcpy_aarch64 (void *__restrict, const void *__restrict, size_t);
-void *__memmove_aarch64 (void *__restrict, const void *__restrict, size_t);
-void *__memset_aarch64 (void *, int, size_t);
-void *__memchr_aarch64 (const void *, int, size_t);
-int __memcmp_aarch64 (const void *, const void *, size_t);
-char *__strcpy_aarch64 (char *__restrict, const char *__restrict);
-int __strcmp_aarch64 (const char *, const char *);
-char *__strchr_aarch64 (const char *, int);
-char *__strchrnul_aarch64 (const char *, int );
-size_t __strlen_aarch64 (const char *);
-size_t __strnlen_aarch64 (const char *, size_t);
-int __strncmp_aarch64 (const char *, const char *, size_t);
-# if __ARM_FEATURE_SVE
-void *__memchr_aarch64_sve (const void *, int, size_t);
-int __memcmp_aarch64_sve (const void *, const void *, size_t);
-char *__strchr_aarch64_sve (const char *, int);
-char *__strrchr_aarch64_sve (const char *, int);
-char *__strchrnul_aarch64_sve (const char *, int );
-int __strcmp_aarch64_sve (const char *, const char *);
-char *__strcpy_aarch64_sve (char *__restrict, const char *__restrict);
-size_t __strlen_aarch64_sve (const char *);
-size_t __strnlen_aarch64_sve (const char *, size_t);
-int __strncmp_aarch64_sve (const char *, const char *, size_t);
-# endif
-#elif __arm__
-void *__memcpy_arm (void *__restrict, const void *__restrict, size_t);
-void *__memset_arm (void *, int, size_t);
-void *__memchr_arm (const void *, int, size_t);
-char *__strcpy_arm (char *__restrict, const char *__restrict);
-int __strcmp_arm (const char *, const char *);
-int __strcmp_armv6m (const char *, const char *);
-size_t __strlen_armv6t2 (const char *);
-#endif
diff --git a/string/memchr.S b/string/memchr.S
deleted file mode 100644
index 0a564d8..0000000
--- a/string/memchr.S
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Selected possible memchr implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/memchr.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/memchr-sve.S"
-# endif
-#elif __arm__
-#include "arm/memchr.S"
-#endif
diff --git a/string/memcmp.S b/string/memcmp.S
deleted file mode 100644
index 22da685..0000000
--- a/string/memcmp.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Selected possible memcpy implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/memcmp.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/memcmp-sve.S"
-# endif
-#endif
diff --git a/string/memcpy.S b/string/memcpy.S
deleted file mode 100644
index c0f23e3..0000000
--- a/string/memcpy.S
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Selected possible memcpy implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/memcpy.S"
-#elif __arm__
-#include "arm/memcpy.S"
-#endif
diff --git a/string/memcpy_bytewise.S b/string/memcpy_bytewise.S
deleted file mode 100644
index 7ee3474..0000000
--- a/string/memcpy_bytewise.S
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Trivial AArch64 memcpy.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "asmdefs.h"
-
-ENTRY (__memcpy_bytewise)
- cbz x2, 2f
- mov x3, 0
-1:
- ldrb w4, [x1, x3]
- strb w4, [x0, x3]
- add x3, x3, 1
- cmp x3, x2
- bne 1b
-2:
- ret
-END (__memcpy_bytewise)
-#endif
diff --git a/string/memmove.S b/string/memmove.S
deleted file mode 100644
index be3c7a1..0000000
--- a/string/memmove.S
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Selected possible memmmove implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/memmove.S"
-#endif
diff --git a/string/memset.S b/string/memset.S
deleted file mode 100644
index 57542ef..0000000
--- a/string/memset.S
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Selected possible memset implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/memset.S"
-#elif __arm__
-#include "arm/memset.S"
-#endif
diff --git a/string/strchr.S b/string/strchr.S
deleted file mode 100644
index 8cead02..0000000
--- a/string/strchr.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Selected possible strchr implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/strchr.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/strchr-sve.S"
-# endif
-#endif
diff --git a/string/strchrnul.S b/string/strchrnul.S
deleted file mode 100644
index 3dfdeef..0000000
--- a/string/strchrnul.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Selected possible strchr implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/strchrnul.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/strchrnul-sve.S"
-# endif
-#endif
diff --git a/string/strcmp.S b/string/strcmp.S
deleted file mode 100644
index 12530ec..0000000
--- a/string/strcmp.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Selected possible strcmp implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/strcmp.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/strcmp-sve.S"
-# endif
-#elif __arm__
-# if __ARM_ARCH >= 7 && __ARM_ARCH_ISA_ARM >= 1
-#include "arm/strcmp.S"
-# elif __ARM_ARCH == 6 && __ARM_ARCH_6M__ >= 1
-#include "arm/strcmp-armv6m.S"
-# endif
-#endif
diff --git a/string/strcpy-c.c b/string/strcpy-c.c
deleted file mode 100644
index 6bde24a..0000000
--- a/string/strcpy-c.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Selected possible strcpy implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __arm__ && defined (__thumb2__) && !defined (__thumb__)
-#include "arm/strcpy.c"
-#endif
diff --git a/string/strcpy.S b/string/strcpy.S
deleted file mode 100644
index a604b22..0000000
--- a/string/strcpy.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Selected possible strcpy implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/strcpy.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/strcpy-sve.S"
-# endif
-#endif
diff --git a/string/strlen.S b/string/strlen.S
deleted file mode 100644
index d681033..0000000
--- a/string/strlen.S
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Selected possible strlen implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/strlen.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/strlen-sve.S"
-# endif
-#elif __arm__
-# if __ARM_ARCH >= 6 && __ARM_ARCH_ISA_THUMB == 2
-#include "arm/strlen-armv6t2.S"
-# endif
-#endif
diff --git a/string/strncmp.S b/string/strncmp.S
deleted file mode 100644
index 26b56b7..0000000
--- a/string/strncmp.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Selected possible strncmp implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/strncmp.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/strncmp-sve.S"
-# endif
-#endif
diff --git a/string/strnlen.S b/string/strnlen.S
deleted file mode 100644
index eebe777..0000000
--- a/string/strnlen.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Selected possible strnlen implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-#include "aarch64/strnlen.S"
-# if __ARM_FEATURE_SVE
-#include "aarch64/strnlen-sve.S"
-# endif
-#endif
diff --git a/string/strrchr.S b/string/strrchr.S
deleted file mode 100644
index 18b1cf9..0000000
--- a/string/strrchr.S
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Selected possible strrchr implementations.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#if __aarch64__
-# if __ARM_FEATURE_SVE
-#include "aarch64/strrchr-sve.S"
-# endif
-#endif
diff --git a/string/test/memchr.c b/string/test/memchr.c
deleted file mode 100644
index 8d609c9..0000000
--- a/string/test/memchr.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * memchr test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- void *(*fun)(const void *, int c, size_t n);
-} funtab[] = {
-#define F(x) {#x, x},
-F(memchr)
-#if __aarch64__
-F(__memchr_aarch64)
-# if __ARM_FEATURE_SVE
-F(__memchr_aarch64_sve)
-# endif
-#elif __arm__
-F(__memchr_arm)
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define SP 512
-#define LEN 250000
-static unsigned char sbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int align, int seekpos, int len)
-{
- unsigned char *src = alignup(sbuf);
- unsigned char *s = src + align;
- unsigned char *f = len ? s + seekpos : 0;
- int seekchar = 0x1;
- int i;
- void *p;
-
- if (len > LEN || seekpos >= len || align >= A)
- abort();
-
- for (i = 0; i < seekpos; i++)
- s[i] = 'a' + i%23;
- s[i++] = seekchar;
- for (; i < len; i++)
- s[i] = 'a' + i%23;
-
- p = fun->fun(s, seekchar, len);
-
- if (p != f) {
- ERR("%s(%p,0x%02x,%d) returned %p\n", fun->name, s, seekchar, len, p);
- ERR("expected: %p\n", f);
- abort();
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int a = 0; a < A; a++) {
- for (int n = 0; n < 100; n++)
- for (int sp = 0; sp < n-1; sp++)
- test(funtab+i, a, sp, n);
- for (int n = 100; n < LEN; n *= 2) {
- test(funtab+i, a, n-1, n);
- test(funtab+i, a, n/2, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/memcmp.c b/string/test/memcmp.c
deleted file mode 100644
index 63b07bd..0000000
--- a/string/test/memcmp.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * memcmp test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- int (*fun)(const void *s1, const void *s2, size_t n);
-} funtab[] = {
-#define F(x) {#x, x},
-F(memcmp)
-#if __aarch64__
-F(__memcmp_aarch64)
-# if __ARM_FEATURE_SVE
-F(__memcmp_aarch64_sve)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define LEN 250000
-static unsigned char s1buf[LEN+2*A];
-static unsigned char s2buf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int s1align, int s2align, int len, int diffpos)
-{
- unsigned char *src1 = alignup(s1buf);
- unsigned char *src2 = alignup(s2buf);
- unsigned char *s1 = src1 + s1align;
- unsigned char *s2 = src2 + s2align;
- int r;
-
- if (len > LEN || s1align >= A || s2align >= A)
- abort();
- if (diffpos && diffpos >= len)
- abort();
-
- for (int i = 0; i < len+A; i++)
- src1[i] = src2[i] = '?';
- for (int i = 0; i < len; i++)
- s1[i] = s2[i] = 'a' + i%23;
- if (diffpos)
- s1[diffpos]++;
-
- r = fun->fun(s1, s2, len);
-
- if ((!diffpos && r != 0) || (diffpos && r == 0)) {
- ERR("%s(align %d, align %d, %d) failed, returned %d\n",
- fun->name, s1align, s2align, len, r);
- ERR("src1: %.*s\n", s1align+len+1, src1);
- ERR("src2: %.*s\n", s2align+len+1, src2);
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int d = 0; d < A; d++)
- for (int s = 0; s < A; s++) {
- int n;
- for (n = 0; n < 100; n++) {
- test(funtab+i, d, s, n, 0);
- test(funtab+i, d, s, n, n / 2);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, d, s, n, 0);
- test(funtab+i, d, s, n, n / 2);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/memcpy.c b/string/test/memcpy.c
deleted file mode 100644
index 26ab0ec..0000000
--- a/string/test/memcpy.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * memcpy test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- void *(*fun)(void *, const void *, size_t);
-} funtab[] = {
-#define F(x) {#x, x},
-F(memcpy)
-#if __aarch64__
-F(__memcpy_bytewise)
-F(__memcpy_aarch64)
-#elif __arm__
-F(__memcpy_arm)
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define LEN 250000
-static unsigned char dbuf[LEN+2*A];
-static unsigned char sbuf[LEN+2*A];
-static unsigned char wbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int dalign, int salign, int len)
-{
- unsigned char *src = alignup(sbuf);
- unsigned char *dst = alignup(dbuf);
- unsigned char *want = wbuf;
- unsigned char *s = src + salign;
- unsigned char *d = dst + dalign;
- unsigned char *w = want + dalign;
- void *p;
- int i;
-
- if (len > LEN || dalign >= A || salign >= A)
- abort();
- for (i = 0; i < len+A; i++) {
- src[i] = '?';
- want[i] = dst[i] = '*';
- }
- for (i = 0; i < len; i++)
- s[i] = w[i] = 'a' + i%23;
-
- p = fun->fun(d, s, len);
- if (p != d)
- ERR("%s(%p,..) returned %p\n", fun->name, d, p);
- for (i = 0; i < len+A; i++) {
- if (dst[i] != want[i]) {
- ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len);
- ERR("got : %.*s\n", dalign+len+1, dst);
- ERR("want: %.*s\n", dalign+len+1, want);
- break;
- }
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int d = 0; d < A; d++)
- for (int s = 0; s < A; s++) {
- int n;
- for (n = 0; n < 100; n++)
- test(funtab+i, d, s, n);
- for (; n < LEN; n *= 2)
- test(funtab+i, d, s, n);
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/memmove.c b/string/test/memmove.c
deleted file mode 100644
index 8164383..0000000
--- a/string/test/memmove.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * memmove test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- void *(*fun)(void *, const void *, size_t);
-} funtab[] = {
-#define F(x) {#x, x},
-F(memmove)
-#if __aarch64__
-F(__memmove_aarch64)
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define LEN 250000
-static unsigned char dbuf[LEN+2*A];
-static unsigned char sbuf[LEN+2*A];
-static unsigned char wbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int dalign, int salign, int len)
-{
- unsigned char *src = alignup(sbuf);
- unsigned char *dst = alignup(dbuf);
- unsigned char *want = wbuf;
- unsigned char *s = src + salign;
- unsigned char *d = dst + dalign;
- unsigned char *w = want + dalign;
- void *p;
- int i;
-
- if (len > LEN || dalign >= A || salign >= A)
- abort();
- for (i = 0; i < len+A; i++) {
- src[i] = '?';
- want[i] = dst[i] = '*';
- }
- for (i = 0; i < len; i++)
- s[i] = w[i] = 'a' + i%23;
-
- p = fun->fun(d, s, len);
- if (p != d)
- ERR("%s(%p,..) returned %p\n", fun->name, d, p);
- for (i = 0; i < len+A; i++) {
- if (dst[i] != want[i]) {
- ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len);
- ERR("got : %.*s\n", dalign+len+1, dst);
- ERR("want: %.*s\n", dalign+len+1, want);
- break;
- }
- }
-}
-
-static void test_overlap(const struct fun *fun, int dalign, int salign, int len)
-{
- unsigned char *src = alignup(sbuf);
- unsigned char *dst = alignup(sbuf);
- unsigned char *want = wbuf;
- unsigned char *s = src + salign;
- unsigned char *d = dst + dalign;
- unsigned char *w = wbuf + dalign;
- void *p;
-
- if (len > LEN || dalign >= A || salign >= A)
- abort();
-
- for (int i = 0; i < len+A; i++)
- src[i] = want[i] = '?';
-
- for (int i = 0; i < len; i++)
- s[i] = w[i] = 'a' + i%23;
-
- /* Copy the potential overlap range. */
- if (s < d) {
- for (int i = 0; i < (uintptr_t)d-(uintptr_t)s; i++)
- want[salign+i] = src[salign+i];
- } else {
- for (int i = 0; i < (uintptr_t)s-(uintptr_t)d; i++)
- want[len + dalign + i] = src[len + dalign + i];
- }
-
- p = fun->fun(d, s, len);
- if (p != d)
- ERR("%s(%p,..) returned %p\n", fun->name, d, p);
- for (int i = 0; i < len+A; i++) {
- if (dst[i] != want[i]) {
- ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len);
- ERR("got : %.*s\n", dalign+len+1, dst);
- ERR("want: %.*s\n", dalign+len+1, want);
- abort();
- break;
- }
- }
-}
-
-int main()
-{
- test_overlap(funtab+0, 2, 1, 1);
-
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int d = 0; d < A; d++)
- for (int s = 0; s < A; s++) {
- int n;
- for (n = 0; n < 100; n++) {
- test(funtab+i, d, s, n);
- test_overlap(funtab+i, d, s, n);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, d, s, n);
- test_overlap(funtab+i, d, s, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/memset.c b/string/test/memset.c
deleted file mode 100644
index c0c7ed6..0000000
--- a/string/test/memset.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * memset test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- void *(*fun)(void *s, int c, size_t n);
-} funtab[] = {
-#define F(x) {#x, x},
-F(memset)
-#if __aarch64__
-F(__memset_aarch64)
-#elif __arm__
-F(__memset_arm)
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define LEN 250000
-static unsigned char sbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void err(const char *name, unsigned char *src, int salign, int c, int len)
-{
- ERR("%s(align %d, %d, %d) failed\n", name, salign, c, len);
- ERR("got : %.*s\n", salign+len+1, src);
-}
-
-static void test(const struct fun *fun, int salign, int c, int len)
-{
- unsigned char *src = alignup(sbuf);
- unsigned char *s = src + salign;
- void *p;
- int i;
-
- if (len > LEN || salign >= A)
- abort();
- for (i = 0; i < len+A; i++)
- src[i] = '?';
- for (i = 0; i < len; i++)
- s[i] = 'a' + i%23;
- for (; i<len%A; i++)
- s[i] = '*';
-
- p = fun->fun(s, c, len);
- if (p != s)
- ERR("%s(%p,..) returned %p\n", fun->name, s, p);
-
- for (i = 0; i < salign; i++) {
- if (src[i] != '?') {
- err(fun->name, src, salign, c, len);
- return;
- }
- }
- for (i = salign; i < len; i++) {
- if (src[i] != (unsigned char)c) {
- err(fun->name, src, salign, c, len);
- return;
- }
- }
- for (; i < len%A; i++) {
- if (src[i] != '*') {
- err(fun->name, src, salign, c, len);
- return;
- }
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int s = 0; s < A; s++) {
- int n;
- for (n = 0; n < 100; n++) {
- test(funtab+i, s, 0, n);
- test(funtab+i, s, 0x25, n);
- test(funtab+i, s, 0xaa25, n);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, s, 0, n);
- test(funtab+i, s, 0x25, n);
- test(funtab+i, s, 0xaa25, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strchr.c b/string/test/strchr.c
deleted file mode 100644
index 30c714f..0000000
--- a/string/test/strchr.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * strchr test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- char *(*fun)(const char *s, int c);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strchr)
-#if __aarch64__
-F(__strchr_aarch64)
-# if __ARM_FEATURE_SVE
-F(__strchr_aarch64_sve)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define SP 512
-#define LEN 250000
-static char sbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int align, int seekpos, int len)
-{
- char *src = alignup(sbuf);
- char *s = src + align;
- char *f = seekpos != -1 ? s + seekpos : 0;
- int seekchar = 0x1;
- void *p;
-
- if (len > LEN || seekpos >= len - 1 || align >= A)
- abort();
- if (seekchar >= 'a' && seekchar <= 'a' + 23)
- abort();
-
- for (int i = 0; i < len + A; i++)
- src[i] = '?';
- for (int i = 0; i < len - 2; i++)
- s[i] = 'a' + i%23;
- if (seekpos != -1)
- s[seekpos] = seekchar;
- s[len - 1] = '\0';
-
- p = fun->fun(s, seekchar);
-
- if (p != f) {
- ERR("%s(%p,0x%02x,%d) returned %p\n", fun->name, s, seekchar, len, p);
- ERR("expected: %p\n", f);
- abort();
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int a = 0; a < A; a++) {
- int n;
- for (n = 1; n < 100; n++) {
- for (int sp = 0; sp < n - 1; sp++)
- test(funtab+i, a, sp, n);
- test(funtab+i, a, -1, n);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, a, -1, n);
- test(funtab+i, a, n / 2, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strchrnul.c b/string/test/strchrnul.c
deleted file mode 100644
index c4260e6..0000000
--- a/string/test/strchrnul.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * strchrnul test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#define _GNU_SOURCE
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- char *(*fun)(const char *s, int c);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strchrnul)
-#if __aarch64__
-F(__strchrnul_aarch64)
-# if __ARM_FEATURE_SVE
-F(__strchrnul_aarch64_sve)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define SP 512
-#define LEN 250000
-static char sbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int align, int seekpos, int len)
-{
- char *src = alignup(sbuf);
- char *s = src + align;
- char *f = seekpos != -1 ? s + seekpos : s + len - 1;
- int seekchar = 0x1;
- void *p;
-
- if (len > LEN || seekpos >= len - 1 || align >= A)
- abort();
- if (seekchar >= 'a' && seekchar <= 'a' + 23)
- abort();
-
- for (int i = 0; i < len + A; i++)
- src[i] = '?';
- for (int i = 0; i < len - 2; i++)
- s[i] = 'a' + i%23;
- if (seekpos != -1)
- s[seekpos] = seekchar;
- s[len - 1] = '\0';
-
- p = fun->fun(s, seekchar);
-
- if (p != f) {
- ERR("%s(%p,0x%02x,%d) returned %p\n", fun->name, s, seekchar, len, p);
- ERR("expected: %p\n", f);
- abort();
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int a = 0; a < A; a++) {
- int n;
- for (n = 1; n < 100; n++) {
- for (int sp = 0; sp < n - 1; sp++)
- test(funtab+i, a, sp, n);
- test(funtab+i, a, -1, n);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, a, -1, n);
- test(funtab+i, a, n / 2, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strcmp.c b/string/test/strcmp.c
deleted file mode 100644
index c4e8867..0000000
--- a/string/test/strcmp.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * strcmp test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- int (*fun)(const char *s1, const char *s2);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strcmp)
-#if __aarch64__
-F(__strcmp_aarch64)
-# if __ARM_FEATURE_SVE
-F(__strcmp_aarch64_sve)
-# endif
-#elif __arm__
-# if __ARM_ARCH >= 7 && __ARM_ARCH_ISA_ARM >= 1
-F(__strcmp_arm)
-# elif __ARM_ARCH == 6 && __ARM_ARCH_6M__ >= 1
-F(__strcmp_armv6m)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define LEN 250000
-static char s1buf[LEN+2*A];
-static char s2buf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int s1align, int s2align, int len, int diffpos)
-{
- char *src1 = alignup(s1buf);
- char *src2 = alignup(s2buf);
- char *s1 = src1 + s1align;
- char *s2 = src2 + s2align;
- int r;
-
- if (len > LEN || s1align >= A || s2align >= A)
- abort();
- if (diffpos > 1 && diffpos >= len-1)
- abort();
-
- for (int i = 0; i < len+A; i++)
- src1[i] = src2[i] = '?';
- for (int i = 0; i < len-1; i++)
- s1[i] = s2[i] = 'a' + i%23;
- if (diffpos > 1)
- s1[diffpos]++;
- s1[len] = s2[len] = '\0';
-
- r = fun->fun(s1, s2);
-
- if (((diffpos <= 1) && r != 0) || (diffpos > 1 && r == 0)) {
- ERR("%s(align %d, align %d, %d) failed, returned %d\n",
- fun->name, s1align, s2align, len, r);
- ERR("src1: %.*s\n", s1align+len+1, src1);
- ERR("src2: %.*s\n", s2align+len+1, src2);
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int d = 0; d < A; d++)
- for (int s = 0; s < A; s++) {
- int n;
- for (n = 0; n < 100; n++) {
- test(funtab+i, d, s, n, 0);
- test(funtab+i, d, s, n, n / 2);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, d, s, n, 0);
- test(funtab+i, d, s, n, n / 2);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strcpy.c b/string/test/strcpy.c
deleted file mode 100644
index 3072ade..0000000
--- a/string/test/strcpy.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * strcpy test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- char *(*fun)(char *dest, const char *src);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strcpy)
-#if __aarch64__
-F(__strcpy_aarch64)
-# if __ARM_FEATURE_SVE
-F(__strcpy_aarch64_sve)
-# endif
-#elif __arm__ && defined (__thumb2__) && !defined (__thumb__)
-F(__strcpy_arm)
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define LEN 250000
-static char dbuf[LEN+2*A];
-static char sbuf[LEN+2*A];
-static char wbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int dalign, int salign, int len)
-{
- char *src = alignup(sbuf);
- char *dst = alignup(dbuf);
- char *want = wbuf;
- char *s = src + salign;
- char *d = dst + dalign;
- char *w = want + dalign;
- void *p;
- int i;
-
- if (len > LEN || dalign >= A || salign >= A)
- abort();
- for (i = 0; i < len+A; i++) {
- src[i] = '?';
- want[i] = dst[i] = '*';
- }
- for (i = 0; i < len-1; i++)
- s[i] = w[i] = 'a' + i%23;
- s[i] = w[i] = '\0';
-
- p = fun->fun(d, s);
- if (p != d)
- ERR("%s(%p,..) returned %p\n", fun->name, d, p);
- for (i = 0; i < len+A; i++) {
- if (dst[i] != want[i]) {
- ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len);
- ERR("got : %.*s\n", dalign+len+1, dst);
- ERR("want: %.*s\n", dalign+len+1, want);
- break;
- }
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int d = 0; d < A; d++)
- for (int s = 0; s < A; s++) {
- int n;
- for (n = 0; n < 100; n++)
- test(funtab+i, d, s, n);
- for (; n < LEN; n *= 2)
- test(funtab+i, d, s, n);
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strlen.c b/string/test/strlen.c
deleted file mode 100644
index 700c865..0000000
--- a/string/test/strlen.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * strlen test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- size_t (*fun)(const char *s);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strlen)
-#if __aarch64__
-F(__strlen_aarch64)
-# if __ARM_FEATURE_SVE
-F(__strlen_aarch64_sve)
-# endif
-#elif __arm__
-# if __ARM_ARCH >= 6 && __ARM_ARCH_ISA_THUMB == 2
-F(__strlen_armv6t2)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define SP 512
-#define LEN 250000
-static char sbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int align, int len)
-{
- char *src = alignup(sbuf);
- char *s = src + align;
- size_t r;
-
- if (len > LEN || align >= A)
- abort();
-
- for (int i = 0; i < len + A; i++)
- src[i] = '?';
- for (int i = 0; i < len - 2; i++)
- s[i] = 'a' + i%23;
- s[len - 1] = '\0';
-
- r = fun->fun(s);
- if (r != len-1) {
- ERR("%s(%p) returned %zu\n", fun->name, s, r);
- ERR("input: %.*s\n", align+len+1, src);
- ERR("expected: %d\n", len);
- abort();
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int a = 0; a < A; a++) {
- int n;
- for (n = 1; n < 100; n++)
- test(funtab+i, a, n);
- for (; n < LEN; n *= 2)
- test(funtab+i, a, n);
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strncmp.c b/string/test/strncmp.c
deleted file mode 100644
index 14e0a8c..0000000
--- a/string/test/strncmp.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * strncmp test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- int (*fun)(const char *, const char *, size_t);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strncmp)
-#if __aarch64__
-F(__strncmp_aarch64)
-# if __ARM_FEATURE_SVE
-F(__strncmp_aarch64_sve)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define LEN 250000
-static char s1buf[LEN+2*A];
-static char s2buf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int s1align, int s2align, int maxlen, int diffpos, int len)
-{
- char *src1 = alignup(s1buf);
- char *src2 = alignup(s2buf);
- char *s1 = src1 + s1align;
- char *s2 = src2 + s2align;
- int r;
-
- if (len > LEN || s1align >= A || s2align >= A)
- abort();
- if (diffpos > 1 && diffpos >= len-1)
- abort();
-
- for (int i = 0; i < len+A; i++)
- src1[i] = src2[i] = '?';
- for (int i = 0; i < len-1; i++)
- s1[i] = s2[i] = 'a' + i%23;
- if (diffpos > 1)
- s1[diffpos]++;
- s1[len] = s2[len] = '\0';
-
- r = fun->fun(s1, s2, maxlen);
-
- diffpos = maxlen <= diffpos ? 0 : diffpos;
-
- if (((diffpos <= 1) && r != 0) || (diffpos > 1 && r == 0)) {
- ERR("%s(align %d, align %d, %d (%d)) failed, returned %d (%d)\n",
- fun->name, s1align, s2align, maxlen, len, r, diffpos);
- ERR("src1: %.*s\n", s1align+len+1, src1);
- ERR("src2: %.*s\n", s2align+len+1, src2);
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int d = 0; d < A; d++)
- for (int s = 0; s < A; s++) {
- int n;
- for (n = 0; n < 100; n++) {
- test(funtab+i, d, s, n, 0, n);
- test(funtab+i, d, s, n, n/2, n);
- test(funtab+i, d, s, n/2, 0, n);
- test(funtab+i, d, s, n/2, n/2, n);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, d, s, n, 0, n);
- test(funtab+i, d, s, n, n/2, n);
- test(funtab+i, d, s, n/2, 0, n);
- test(funtab+i, d, s, n/2, n/2, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strnlen.c b/string/test/strnlen.c
deleted file mode 100644
index 9a98d80..0000000
--- a/string/test/strnlen.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * strnlen test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#define _POSIX_C_SOURCE 200809L
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- size_t (*fun)(const char *s, size_t m);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strnlen)
-#if __aarch64__
-F(__strnlen_aarch64)
-# if __ARM_FEATURE_SVE
-F(__strnlen_aarch64_sve)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define SP 512
-#define LEN 250000
-static char sbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int align, int maxlen, int len)
-{
- char *src = alignup(sbuf);
- char *s = src + align;
- size_t r;
- size_t e = maxlen < len ? maxlen : len - 1;
-
- if (len > LEN || align >= A)
- abort();
-
- for (int i = 0; i < len + A; i++)
- src[i] = '?';
- for (int i = 0; i < len - 2; i++)
- s[i] = 'a' + i%23;
- s[len - 1] = '\0';
-
- r = fun->fun(s, maxlen);
- if (r != e) {
- ERR("%s(%p) returned %zu\n", fun->name, s, r);
- ERR("input: %.*s\n", align+len+1, src);
- ERR("expected: %d\n", len);
- abort();
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int a = 0; a < A; a++) {
- int n;
- for (n = 1; n < 100; n++)
- for (int maxlen = 0; maxlen < 100; maxlen++)
- test(funtab+i, a, maxlen, n);
- for (; n < LEN; n *= 2) {
- test(funtab+i, a, n*2, n);
- test(funtab+i, a, n, n);
- test(funtab+i, a, n/2, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/string/test/strrchr.c b/string/test/strrchr.c
deleted file mode 100644
index b3fc2a9..0000000
--- a/string/test/strrchr.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * strrchr test.
- *
- * Copyright (c) 2019, Arm Limited.
- * SPDX-License-Identifier: MIT
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include "stringlib.h"
-
-static const struct fun
-{
- const char *name;
- char *(*fun)(const char *s, int c);
-} funtab[] = {
-#define F(x) {#x, x},
-F(strrchr)
-#if __aarch64__
-# if __ARM_FEATURE_SVE
-F(__strrchr_aarch64_sve)
-# endif
-#endif
-#undef F
- {0, 0}
-};
-
-static int test_status;
-#define ERR(...) (test_status=1, printf(__VA_ARGS__))
-
-#define A 32
-#define SP 512
-#define LEN 250000
-static char sbuf[LEN+2*A];
-
-static void *alignup(void *p)
-{
- return (void*)(((uintptr_t)p + A-1) & -A);
-}
-
-static void test(const struct fun *fun, int align, int seekpos, int len)
-{
- char *src = alignup(sbuf);
- char *s = src + align;
- char *f = seekpos != -1 ? s + seekpos : 0;
- int seekchar = 0x1;
- void *p;
-
- if (len > LEN || seekpos >= len - 1 || align >= A)
- abort();
- if (seekchar >= 'a' && seekchar <= 'a' + 23)
- abort();
-
- for (int i = 0; i < len + A; i++)
- src[i] = '?';
- for (int i = 0; i < len - 2; i++)
- s[i] = 'a' + i%23;
- if (seekpos != -1)
- s[seekpos/2] = s[seekpos] = seekchar;
- s[len - 1] = '\0';
-
- p = fun->fun(s, seekchar);
-
- if (p != f) {
- ERR("%s(%p,0x%02x,%d) returned %p\n", fun->name, s, seekchar, len, p);
- ERR("expected: %p\n", f);
- abort();
- }
-}
-
-int main()
-{
- int r = 0;
- for (int i=0; funtab[i].name; i++) {
- test_status = 0;
- for (int a = 0; a < A; a++) {
- int n;
- for (n = 1; n < 100; n++) {
- for (int sp = 0; sp < n - 1; sp++)
- test(funtab+i, a, sp, n);
- test(funtab+i, a, -1, n);
- }
- for (; n < LEN; n *= 2) {
- test(funtab+i, a, -1, n);
- test(funtab+i, a, n / 2, n);
- }
- }
- if (test_status) {
- r = -1;
- ERR("FAIL %s\n", funtab[i].name);
- }
- }
- return r;
-}
diff --git a/math/test/mathbench.c b/test/mathbench.c
index 1266d11..1266d11 100644
--- a/math/test/mathbench.c
+++ b/test/mathbench.c
diff --git a/math/test/mathtest.c b/test/mathtest.c
index 6ea3953..f535452 100644
--- a/math/test/mathtest.c
+++ b/test/mathtest.c
@@ -40,6 +40,8 @@
_Pragma(STR(import IMPORT_SYMBOL))
#endif
+EXTERN_C int __ieee754_rem_pio2(double, double *);
+
int dmsd, dlsd;
int quiet = 0;
@@ -1092,6 +1094,7 @@ int runtest(testdetail t) {
case m_islessgreaterf: intres = islessgreater(s_arg1.f, s_arg2.f); break;
case m_isunorderedf: intres = isunordered(s_arg1.f, s_arg2.f); break;
+ case m_rred: intres = 3 & __ieee754_rem_pio2(d_arg1.f, d_res.da); break;
default:
printf("unhandled macro: %s\n",t.func->name);
return test_fail;
diff --git a/math/test/rtest/dotest.c b/test/rtest/dotest.c
index f416477..f416477 100644
--- a/math/test/rtest/dotest.c
+++ b/test/rtest/dotest.c
diff --git a/math/test/rtest/intern.h b/test/rtest/intern.h
index af574b0..af574b0 100644
--- a/math/test/rtest/intern.h
+++ b/test/rtest/intern.h
diff --git a/math/test/rtest/main.c b/test/rtest/main.c
index e94e455..e94e455 100644
--- a/math/test/rtest/main.c
+++ b/test/rtest/main.c
diff --git a/math/test/rtest/random.c b/test/rtest/random.c
index e97a8c6..e97a8c6 100644
--- a/math/test/rtest/random.c
+++ b/test/rtest/random.c
diff --git a/math/test/rtest/random.h b/test/rtest/random.h
index c1ce956..c1ce956 100644
--- a/math/test/rtest/random.h
+++ b/test/rtest/random.h
diff --git a/math/test/rtest/semi.c b/test/rtest/semi.c
index 938dc3a..938dc3a 100644
--- a/math/test/rtest/semi.c
+++ b/test/rtest/semi.c
diff --git a/math/test/rtest/semi.h b/test/rtest/semi.h
index da473a2..da473a2 100644
--- a/math/test/rtest/semi.h
+++ b/test/rtest/semi.h
diff --git a/math/test/rtest/types.h b/test/rtest/types.h
index 1a76c2e..1a76c2e 100644
--- a/math/test/rtest/types.h
+++ b/test/rtest/types.h
diff --git a/math/test/rtest/wrappers.c b/test/rtest/wrappers.c
index acaf671..acaf671 100644
--- a/math/test/rtest/wrappers.c
+++ b/test/rtest/wrappers.c
diff --git a/math/test/rtest/wrappers.h b/test/rtest/wrappers.h
index 5804935..5804935 100644
--- a/math/test/rtest/wrappers.h
+++ b/test/rtest/wrappers.h
diff --git a/math/test/testcases/directed/cosf.tst b/test/testcases/directed/cosf.tst
index 5dc0994..5dc0994 100644
--- a/math/test/testcases/directed/cosf.tst
+++ b/test/testcases/directed/cosf.tst
diff --git a/math/test/testcases/directed/exp.tst b/test/testcases/directed/exp.tst
index addfc0a..addfc0a 100644
--- a/math/test/testcases/directed/exp.tst
+++ b/test/testcases/directed/exp.tst
diff --git a/math/test/testcases/directed/exp2.tst b/test/testcases/directed/exp2.tst
index 04a5a50..04a5a50 100644
--- a/math/test/testcases/directed/exp2.tst
+++ b/test/testcases/directed/exp2.tst
diff --git a/math/test/testcases/directed/exp2f.tst b/test/testcases/directed/exp2f.tst
index 2b6a9b5..2b6a9b5 100644
--- a/math/test/testcases/directed/exp2f.tst
+++ b/test/testcases/directed/exp2f.tst
diff --git a/math/test/testcases/directed/expf.tst b/test/testcases/directed/expf.tst
index 74664c7..74664c7 100644
--- a/math/test/testcases/directed/expf.tst
+++ b/test/testcases/directed/expf.tst
diff --git a/math/test/testcases/directed/log.tst b/test/testcases/directed/log.tst
index eeb762c..eeb762c 100644
--- a/math/test/testcases/directed/log.tst
+++ b/test/testcases/directed/log.tst
diff --git a/math/test/testcases/directed/log2.tst b/test/testcases/directed/log2.tst
index e0765d8..e0765d8 100644
--- a/math/test/testcases/directed/log2.tst
+++ b/test/testcases/directed/log2.tst
diff --git a/math/test/testcases/directed/log2f.tst b/test/testcases/directed/log2f.tst
index 8d685ba..8d685ba 100644
--- a/math/test/testcases/directed/log2f.tst
+++ b/test/testcases/directed/log2f.tst
diff --git a/math/test/testcases/directed/logf.tst b/test/testcases/directed/logf.tst
index 7ccc873..7ccc873 100644
--- a/math/test/testcases/directed/logf.tst
+++ b/test/testcases/directed/logf.tst
diff --git a/math/test/testcases/directed/pow.tst b/test/testcases/directed/pow.tst
index a4c42be..a4c42be 100644
--- a/math/test/testcases/directed/pow.tst
+++ b/test/testcases/directed/pow.tst
diff --git a/math/test/testcases/directed/powf.tst b/test/testcases/directed/powf.tst
index efd1dd5..efd1dd5 100644
--- a/math/test/testcases/directed/powf.tst
+++ b/test/testcases/directed/powf.tst
diff --git a/test/testcases/directed/rred.tst b/test/testcases/directed/rred.tst
new file mode 100644
index 0000000..41e4e70
--- /dev/null
+++ b/test/testcases/directed/rred.tst
@@ -0,0 +1,96 @@
+; rred.tst
+;
+; Copyright (c) 1999-2018, Arm Limited.
+; SPDX-License-Identifier: MIT
+
+func=rred op1=40000000.00000000 result=3fdb7812.aeef4b9e.e59 res2=00000001 errno=0
+func=rred op1=400fffff.ffffffff result=bfe6cbe3.f9990e95.a79 res2=00000003 errno=0
+func=rred op1=40100000.00000000 result=bfe6cbe3.f9990e91.a79 res2=00000003 errno=0
+func=rred op1=4012d97c.7f3321d2 result=bcaa7939.4c9e8a0a.515 res2=00000003 errno=0
+func=rred op1=401c90fd.aa22168c result=bfe6cbe3.f9990e92.c1f res2=00000001 errno=0
+func=rred op1=401f6a7a.2955385f result=3cc4f828.2013467b.b36 res2=00000001 errno=0
+func=rred op1=40200000.00000000 result=3fc2b0ba.d558f434.f82 res2=00000001 errno=0
+func=rred op1=4025fdbb.e9bba775 result=bcbee2c2.d963a10c.099 res2=00000003 errno=0
+func=rred op1=402c463a.beccb2bc result=3cd6128a.83448c3c.217 res2=00000001 errno=0
+func=rred op1=402c90fd.aa22168c result=3fc2b0ba.d558f42c.251 res2=00000001 errno=0
+func=rred op1=40300000.00000000 result=3fd2b0ba.d558f434.f82 res2=00000002 errno=0
+func=rred op1=4031475c.c9eedf00 result=bce6111d.218effa2.5d5 res2=00000003 errno=0
+func=rred op1=403dd85a.7410f58d result=3cc61565.46afa56f.a9d res2=00000003 errno=0
+func=rred op1=403fb53d.14aa9c2f result=3fd2b0ba.d558f429.f05 res2=00000000 errno=0
+func=rred op1=4046c6cb.c45dc8de result=3c26d61b.58c99c42.f13 res2=00000001 errno=0
+func=rred op1=4049eb0b.2ee64e81 result=bcb19abb.2567f738.bf7 res2=00000001 errno=0
+func=rred op1=404fb53d.14aa9c2a result=3fe2b0ba.d558f2e9.f05 res2=00000000 errno=0
+func=rred op1=404fb53d.14aa9c34 result=3fe2b0ba.d558f569.f05 res2=00000000 errno=0
+func=rred op1=4051abe4.b73fefb5 result=bcd1a34b.6fa942d3.588 res2=00000001 errno=0
+func=rred op1=405f05f2.3c0427aa result=3cc1b746.c796f33c.131 res2=00000003 errno=0
+func=rred op1=405fb53d.14aa9c20 result=bfd9c501.fbacf2b9.592 res2=00000001 errno=0
+func=rred op1=405fb53d.14aa9c34 result=bfd9c501.fbacdeb9.592 res2=00000001 errno=0
+func=rred op1=406ae65f.0030f844 result=3cc1c2b1.d543580a.349 res2=00000001 errno=0
+func=rred op1=406e0a9e.6ab97de7 result=bcc1899a.90e56003.8d3 res2=00000001 errno=0
+func=rred op1=406fb53d.14aa9c20 result=3fe87ef4.acdb6777.340 res2=00000001 errno=0
+func=rred op1=406fb53d.14aa9c34 result=3fe87ef4.acdb7b77.340 res2=00000001 errno=0
+func=rred op1=4078d695.62476091 result=3cc1d987.f09c21a6.778 res2=00000001 errno=0
+func=rred op1=407bfad4.cccfe634 result=bcda5f88.6ddaa73a.860 res2=00000001 errno=0
+func=rred op1=407fb53d.14aa9c30 result=bfa460d4.ed16b422.511 res2=00000003 errno=0
+func=rred op1=407fe781.0b53247a result=bfa460d4.ed18ba33.f74 res2=00000001 errno=0
+func=rred op1=40821cfd.a23b2280 result=3cc1f05e.0bf4eb42.ba7 res2=00000001 errno=0
+func=rred op1=408b7099.e6806f3c result=bcc139ad.312e9e60.a2f res2=00000003 errno=0
+func=rred op1=408fb53d.14aa9c30 result=bfb460d4.ed16b422.511 res2=00000002 errno=0
+func=rred op1=408fe781.0b53247a result=bfb460d4.ed18ba33.f74 res2=00000002 errno=0
+func=rred op1=409471e4.b34c75af result=3cc24bb6.795811b3.c63 res2=00000001 errno=0
+func=rred op1=40991bb2.d56f1c0d result=bcc0de54.c3cb77ef.972 res2=00000003 errno=0
+func=rred op1=409ff412.08fd45ee result=bfc460d4.ed2d0bb8.60c res2=00000002 errno=0
+func=rred op1=409ff412.08fd4733 result=bfc460d4.ed046bb8.60c res2=00000002 errno=0
+func=rred op1=40ab4e0b.2cec917e result=3cc35dbf.c1818506.e98 res2=00000001 errno=0
+func=rred op1=40ada2f2.3dfde4ad result=bcbf9896.f7440938.e7b res2=00000003 errno=0
+func=rred op1=40affa5a.87d256f9 result=bfd460d4.ed2d147a.959 res2=00000002 errno=0
+func=rred op1=40affa5a.87d257d2 result=bfd460d4.ed11f47a.959 res2=00000002 errno=0
+func=rred op1=40b90a6b.78a52d2e result=3cc4cb21.770e1ecb.189 res2=00000001 errno=0
+func=rred op1=40bfe691.f24548fd result=bcbb5071.d69e3bec.5a7 res2=00000003 errno=0
+func=rred op1=40bffd7e.c73cdcf3 result=bfe460d4.ed7e88db.aff res2=00000002 errno=0
+func=rred op1=40bffd7e.c73ce20a result=bfe460d4.ecdba8db.aff res2=00000002 errno=0
+func=rred op1=40c5a4fb.ea3a16b6 result=bcb875ae.6b850863.fc5 res2=00000003 errno=0
+func=rred op1=40c7e89b.9e817b06 result=3cc7a5e4.e2275253.76c res2=00000001 errno=0
+func=rred op1=40cfff10.e6f21c1e result=3fd30499.988aa830.25d res2=00000001 errno=0
+func=rred op1=40cfff10.e6f2264d result=3fd30499.9da22830.25d res2=00000001 errno=0
+func=rred op1=40d635e3.d74befca result=bcaa1541.7e407485.076 res2=00000003 errno=0
+func=rred op1=40d757b3.b16fa1f2 result=3ccd5b6b.b859b964.331 res2=00000001 errno=0
+func=rred op1=40dfff10.e6f2264d result=3fe30499.9da22830.25d res2=00000002 errno=0
+func=rred op1=40dfffd9.f6ccbe3f result=3fe30499.988a73cf.0b7 res2=00000000 errno=0
+func=rred op1=40e5ed6f.e0c30340 result=bccefafe.cb152585.3e2 res2=00000001 errno=0
+func=rred op1=40e67e57.cdd4dc54 result=3ca396f5.3352c400.db0 res2=00000003 errno=0
+func=rred op1=40efffd9.f6cca9e0 result=bfd87587.17a4e524.ec7 res2=00000001 errno=0
+func=rred op1=40efffd9.f6ccd29e result=bfd87586.c628e524.ec7 res2=00000001 errno=0
+func=rred op1=40f65a1d.d290660f result=bcb049c6.e4971284.99e res2=00000001 errno=0
+func=rred op1=40f6a291.c9195299 result=3ccbbbd8.a59e4d43.27f res2=00000003 errno=0
+func=rred op1=40ffffd9.f6cca9e0 result=bfe87587.17a4e524.ec7 res2=00000002 errno=0
+func=rred op1=40ffffd9.f6ccd29e result=bfe87586.c628e524.ec7 res2=00000002 errno=0
+func=rred op1=4100dec1.da5fa53f result=3cbd626f.ccfc2601.489 res2=00000001 errno=0
+func=rred op1=410bf9b3.c6059d24 result=bcb6c813.2f84c308.c64 res2=00000001 errno=0
+func=rred op1=410fffd9.f6ccca78 result=3fa58e8f.b9e8fe6b.441 res2=00000003 errno=0
+func=rred op1=410ffff3.18c7fe24 result=3fa58e87.93ddb859.9df res2=00000001 errno=0
+func=rred op1=41139c6f.d67805a7 result=bc8988ef.e18ff83f.598 res2=00000003 errno=0
+func=rred op1=41193c05.c9ed3cbc result=3cb065d7.3720c4f8.efd res2=00000001 errno=0
+func=rred op1=411fff9b.21d874d7 result=3fb58e8e.fc452d97.637 res2=00000000 errno=0
+func=rred op1=411fffff.a9c5a846 result=3fb58e87.93d81550.cae res2=00000000 errno=0
+func=rred op1=41223d98.d86bd573 result=3ccbc9e0.cee3267d.52f res2=00000001 errno=0
+func=rred op1=412a9adc.c7f96cf0 result=bcbd2a4f.27e8c118.9ca res2=00000003 errno=0
+func=rred op1=412fff9b.21d874d7 result=3fc58e8e.fc452d97.637 res2=00000000 errno=0
+func=rred op1=412fffff.a9c5a846 result=3fc58e87.93d81550.cae res2=00000000 errno=0
+func=rred op1=41344bdb.557e1dc1 result=bcd2ae9d.61bc91ca.8a4 res2=00000001 errno=0
+func=rred op1=413fffff.a9c31c60 result=3fd58de4.9a581550.cae res2=00000000 errno=0
+func=rred op1=413fffff.a9c8342c result=3fd58f2a.8d581550.cae res2=00000000 errno=0
+func=rred op1=414ffffc.8587170a result=3fe58ebd.e6f97e12.ffa res2=00000000 errno=0
+func=rred op1=414fffff.a9c31c60 result=3fe58de4.9a581550.cae res2=00000000 errno=0
+func=rred op1=415ffffa.f366e59a result=bfcc9ae3.c1cfd521.646 res2=00000001 errno=0
+func=rred op1=415fffff.a9c31c60 result=bfcca0b5.cf60be3b.dda res2=00000001 errno=0
+func=rred op1=416ffffb.57eea140 result=bfdc9b47.17f13de3.992 res2=00000000 errno=0
+func=rred op1=416fffff.a9c31c60 result=bfdca0b5.cf60be3b.dda res2=00000002 errno=0
+func=rred op1=417fffff.dbde54a8 result=3fe551c4.1816e793.952 res2=00000001 errno=0
+func=rred op1=417fffff.dc2fd169 result=3fe5f4bd.9a16e793.952 res2=00000001 errno=0
+func=rred op1=418fffff.c2f2ac7f result=bfcb1c87.2d275aa1.21c res2=00000001 errno=0
+func=rred op1=418fffff.f5004ffc result=bfce81b9.e5acfda9.f4d res2=00000001 errno=0
+func=rred op1=419fffff.c2eae9c2 result=bfdb98b2.fd275aa1.21c res2=00000002 errno=0
+func=rred op1=419fffff.f5004ffc result=bfde81b9.e5acfda9.f4d res2=00000002 errno=0
+func=rred op1=41afffff.c2e7cf10 result=3fe67998.8b60ff8f.6b7 res2=00000003 errno=0
+func=rred op1=41afffff.fb48ced1 result=3fe3c23c.c1caa825.7df res2=00000001 errno=0
diff --git a/test/testcases/directed/rred2.tst b/test/testcases/directed/rred2.tst
new file mode 100644
index 0000000..558c18e
--- /dev/null
+++ b/test/testcases/directed/rred2.tst
@@ -0,0 +1,516 @@
+; rred2.tst
+;
+; Copyright (c) 1999-2018, Arm Limited.
+; SPDX-License-Identifier: MIT
+
+func=rred op1=4139eb71.48f354d6 result=3c8d0afa.32c646ca.18a res2=00000001 errno=0
+func=rred op1=414344ba.16f4f99a result=3cc23686.da4d2965.916 res2=00000003 errno=0
+func=rred op1=414a4327.087660e3 result=bccb599f.84bc5cab.fb1 res2=00000003 errno=0
+func=rred op1=41569815.aff42738 result=3cc5d7e6.20a5f23e.d47 res2=00000001 errno=0
+func=rred op1=415d3ecc.e1f28274 result=bcad49a4.1d0b3b67.209 res2=00000003 errno=0
+func=rred op1=416841c3.7c73be07 result=3ccd1aa4.ad5783f1.5aa res2=00000001 errno=0
+func=rred op1=416b951f.1572eba5 result=bc3f54f5.227a4e83.fbf res2=00000003 errno=0
+func=rred op1=4174456b.dcf64b08 result=3caccc50.4881522d.10a res2=00000003 errno=0
+func=rred op1=4175ef19.a975e1d7 result=bcc5f73b.15c86c8d.587 res2=00000001 errno=0
+func=rred op1=41817269.26f7c621 result=bcadc6f7.f19524a1.308 res2=00000001 errno=0
+func=rred op1=418e6821.cb71708c result=3cc5993c.3660fda1.cc8 res2=00000001 errno=0
+func=rred op1=419683c4.1e3558e3 result=bcaec19f.9aa8f715.506 res2=00000001 errno=0
+func=rred op1=419956c6.d433ddca result=3cd1ffb2.2d50d35c.2a6 res2=00000003 errno=0
+func=rred op1=41a90c71.99d42244 result=bcb05b77.76684dfe.c81 res2=00000001 errno=0
+func=rred op1=41ae1dcc.9111b506 result=3ca8e1b1.a432085c.912 res2=00000003 errno=0
+func=rred op1=41b19793.c427a3e4 result=3cc49e94.8d4d2b2d.aca res2=00000001 errno=0
+func=rred op1=41bdd377.56b1f980 result=bcf27d06.01dabc96.3a5 res2=00000000 errno=0
+func=rred op1=41bdf8a1.f3e1d743 result=bce0eeea.e7979c10.714 res2=00000001 errno=0
+func=rred op1=41be1dcc.9111b506 result=3cb8e1b1.a432085c.912 res2=00000002 errno=0
+func=rred op1=41c2c955.335f19b3 result=bcc88933.319c74fe.2c2 res2=00000003 errno=0
+func=rred op1=41c55202.aefde314 result=3ca10c74.5b9374bb.922 res2=00000003 errno=0
+func=rred op1=41cb951f.1572eba5 result=bc9f54f5.227a4e83.fbf res2=00000000 errno=0
+func=rred op1=41ce1dcc.9111b506 result=3cc8e1b1.a432085c.912 res2=00000000 errno=0
+func=rred op1=41d0ec1d.bdf3fa1b result=bcb830b4.bf06e19f.c71 res2=00000001 errno=0
+func=rred op1=41d55202.aefde314 result=3cb10c74.5b9374bb.922 res2=00000002 errno=0
+func=rred op1=41db951f.1572eba5 result=bcaf54f5.227a4e83.fbf res2=00000000 errno=0
+func=rred op1=41dffb04.067cd49e result=3cb992ae.895d2f19.5b4 res2=00000001 errno=0
+func=rred op1=41e55202.aefde314 result=3cc10c74.5b9374bb.922 res2=00000000 errno=0
+func=rred op1=41e6409e.69b372e0 result=bcc3ed97.a8220470.e28 res2=00000001 errno=0
+func=rred op1=41eaa683.5abd5bd9 result=3cc54f91.727851ea.76b res2=00000003 errno=0
+func=rred op1=41eb951f.1572eba5 result=bcbf54f5.227a4e83.fbf res2=00000000 errno=0
+func=rred op1=41f55202.aefde314 result=3cd10c74.5b9374bb.922 res2=00000000 errno=0
+func=rred op1=41f5c950.8c58aafa result=bc97091a.64747daa.82d res2=00000001 errno=0
+func=rred op1=41fb1dd1.381823bf result=3ca6945b.84ecaaa1.e2f res2=00000003 errno=0
+func=rred op1=41fb951f.1572eba5 result=bccf54f5.227a4e83.fbf res2=00000000 errno=0
+func=rred op1=42003928.f1ebce42 result=3cbc56a2.1e09ca0c.83a res2=00000001 errno=0
+func=rred op1=4205c950.8c58aafa result=bca7091a.64747daa.82d res2=00000002 errno=0
+func=rred op1=420b1dd1.381823bf result=3cb6945b.84ecaaa1.e2f res2=00000002 errno=0
+func=rred op1=420b5978.26c587b2 result=bcc9afde.413f23db.833 res2=00000003 errno=0
+func=rred op1=4215c950.8c58aafa result=bcb7091a.64747daa.82d res2=00000000 errno=0
+func=rred op1=42189164.598f1956 result=bccf7224.da5c4346.23f res2=00000001 errno=0
+func=rred op1=421b1dd1.381823bf result=3cc6945b.84ecaaa1.e2f res2=00000000 errno=0
+func=rred op1=421de5e5.054e921b result=3c95361e.e6553188.036 res2=00000001 errno=0
+func=rred op1=42246546.a5bd73cc result=bc98dc15.e293c9cd.023 res2=00000003 errno=0
+func=rred op1=4225c950.8c58aafa result=bcc7091a.64747daa.82d res2=00000000 errno=0
+func=rred op1=422c81db.1eb35aed result=3cc93b1f.61b750d2.e36 res2=00000001 errno=0
+func=rred op1=422de5e5.054e921b result=3ca5361e.e6553188.036 res2=00000002 errno=0
+func=rred op1=4233b341.b26fd835 result=3cbb6d24.5efa23fb.43f res2=00000001 errno=0
+func=rred op1=42346546.a5bd73cc result=bca8dc15.e293c9cd.023 res2=00000002 errno=0
+func=rred op1=423de5e5.054e921b result=3cb5361e.e6553188.036 res2=00000000 errno=0
+func=rred op1=423e97e9.f89c2db2 result=bcb2a510.69eed759.c1a res2=00000001 errno=0
+func=rred op1=42446546.a5bd73cc result=bcb8dc15.e293c9cd.023 res2=00000000 errno=0
+func=rred op1=4248cc93.5bdf3528 result=3cc851a1.a2a7aac1.a3b res2=00000001 errno=0
+func=rred op1=42497e98.4f2cd0bf result=bcbf131b.5b38bc40.42b res2=00000003 errno=0
+func=rred op1=424de5e5.054e921b result=3cc5361e.e6553188.036 res2=00000000 errno=0
+func=rred op1=425231a0.4aac931e result=bcdecde1.3b42acba.937 res2=00000003 errno=0
+func=rred op1=42546546.a5bd73cc result=bcc8dc15.e293c9cd.023 res2=00000000 errno=0
+func=rred op1=425bb23e.aa3db16d result=3ca6b244.e2e34d9f.884 res2=00000003 errno=0
+func=rred op1=425de5e5.054e921b result=3cd5361e.e6553188.036 res2=00000000 errno=0
+func=rred op1=426065c8.29d68730 result=bc714e87.fd83e16b.cf2 res2=00000001 errno=0
+func=rred op1=42646546.a5bd73cc result=bcd8dc15.e293c9cd.023 res2=00000000 errno=0
+func=rred op1=426bb23e.aa3db16d result=3cb6b244.e2e34d9f.884 res2=00000002 errno=0
+func=rred op1=426ccc11.d7c621c4 result=3cd80c67.82b19b3b.f47 res2=00000003 errno=0
+func=rred op1=427065c8.29d68730 result=bc814e87.fd83e16b.cf2 res2=00000002 errno=0
+func=rred op1=42737f5a.95526dd5 result=3cc73cb9.22cf6caa.e6c res2=00000003 errno=0
+func=rred op1=427898ac.3ec1cac8 result=bc89f5cb.fc45d221.b6a res2=00000003 errno=0
+func=rred op1=427bb23e.aa3db16d result=3cc6b244.e2e34d9f.884 res2=00000000 errno=0
+func=rred op1=428065c8.29d68730 result=bc914e87.fd83e16b.cf2 res2=00000000 errno=0
+func=rred op1=42847f3a.344c28fc result=bc95a229.fce4d9c6.c2e res2=00000001 errno=0
+func=rred op1=428bb23e.aa3db16d result=3cd6b244.e2e34d9f.884 res2=00000000 errno=0
+func=rred op1=428fcbb0.b4b35339 result=3cd66d0a.c2ed3e19.d90 res2=00000001 errno=0
+func=rred op1=429065c8.29d68730 result=bca14e87.fd83e16b.cf2 res2=00000000 errno=0
+func=rred op1=42927281.2f115816 result=bca37858.fd345d99.490 res2=00000001 errno=0
+func=rred op1=429dbef7.af788253 result=3ce68fa7.d2e845dc.b0a res2=00000001 errno=0
+func=rred op1=429fcbb0.b4b35339 result=3ce66d0a.c2ed3e19.d90 res2=00000002 errno=0
+func=rred op1=42a065c8.29d68730 result=bcb14e87.fd83e16b.cf2 res2=00000000 errno=0
+func=rred op1=42a16c24.ac73efa3 result=bcb26370.7d5c1f82.8c1 res2=00000001 errno=0
+func=rred op1=42aec554.3215eac6 result=3cf67e59.4aeac1fb.44d res2=00000003 errno=0
+func=rred op1=42afcbb0.b4b35339 result=3cf66d0a.c2ed3e19.d90 res2=00000000 errno=0
+func=rred op1=42b06289.b804b08a result=bcfaaf5e.3a50b293.610 res2=00000003 errno=0
+func=rred op1=42b065c8.29d68730 result=bcc14e87.fd83e16b.cf2 res2=00000000 errno=0
+func=rred op1=42bfc872.42e17c93 result=3cf45488.4b3a45cd.caf res2=00000003 errno=0
+func=rred op1=42bfcbb0.b4b35339 result=3d066d0a.c2ed3e19.d90 res2=00000000 errno=0
+func=rred op1=42c06428.f0ed9bdd result=bcfcd92f.3a012ec0.dae res2=00000003 errno=0
+func=rred op1=42c065c8.29d68730 result=bcd14e87.fd83e16b.cf2 res2=00000000 errno=0
+func=rred op1=42cfc6d3.09f89140 result=3cf02383.5bd45535.aec res2=00000001 errno=0
+func=rred op1=42cfc872.42e17c93 result=3d045488.4b3a45cd.caf res2=00000002 errno=0
+func=rred op1=42d065c8.29d68730 result=bce14e87.fd83e16b.cf2 res2=00000000 errno=0
+func=rred op1=42d0e826.ceb0c5c0 result=bd00b905.acac1b50.bef res2=00000003 errno=0
+func=rred op1=42df42d5.2c35675d result=3ce00d67.39fd0716.4b7 res2=00000001 errno=0
+func=rred op1=42dfc6d3.09f89140 result=3d002383.5bd45535.aec res2=00000002 errno=0
+func=rred op1=42e065c8.29d68730 result=bcf14e87.fd83e16b.cf2 res2=00000000 errno=0
+func=rred op1=42e64ac3.e719da9a result=3cafd98b.c01dfeeb.32e res2=00000001 errno=0
+func=rred op1=42e75120.69b7430d result=bc761c21.d74e1f63.5ab res2=00000001 errno=0
+func=rred op1=42ef42d5.2c35675d result=3cf00d67.39fd0716.4b7 res2=00000002 errno=0
+func=rred op1=42f04530.809ff78c result=bce3a491.40e2f9d8.0fb res2=00000001 errno=0
+func=rred op1=42f64ac3.e719da9a result=3cbfd98b.c01dfeeb.32e res2=00000002 errno=0
+func=rred op1=42f75120.69b7430d result=bc861c21.d74e1f63.5ab res2=00000002 errno=0
+func=rred op1=42ff636c.d56bf701 result=3cdd401c.658f2104.023 res2=00000003 errno=0
+func=rred op1=43013b41.2ea2182d result=3caa5283.4a4a7712.5c3 res2=00000003 errno=0
+func=rred op1=43064ac3.e719da9a result=3ccfd98b.c01dfeeb.32e res2=00000000 errno=0
+func=rred op1=43075120.69b7430d result=bc961c21.d74e1f63.5ab res2=00000000 errno=0
+func=rred op1=430d66ff.a4cc6ded result=bcb83752.90cc4b3a.db7 res2=00000001 errno=0
+func=rred op1=43113b41.2ea2182d result=3cba5283.4a4a7712.5c3 res2=00000002 errno=0
+func=rred op1=43144630.cc2cad9d result=3c9e88e4.bd46cec1.5da res2=00000003 errno=0
+func=rred op1=43175120.69b7430d result=bca61c21.d74e1f63.5ab res2=00000000 errno=0
+func=rred op1=431a5c10.0741d87d result=bcbdbe5b.069fd313.b22 res2=00000001 errno=0
+func=rred op1=4322c0b8.fd6762e5 result=3cc0fa5e.3cce1561.59c res2=00000001 errno=0
+func=rred op1=43244630.cc2cad9d result=3cae88e4.bd46cec1.5da res2=00000002 errno=0
+func=rred op1=4325cba8.9af1f855 result=bc8b5ebd.e2aae00a.af8 res2=00000003 errno=0
+func=rred op1=43275120.69b7430d result=bcb61c21.d74e1f63.5ab res2=00000000 errno=0
+func=rred op1=43344630.cc2cad9d result=3cbe88e4.bd46cec1.5da res2=00000000 errno=0
+func=rred op1=433508ec.b38f52f9 result=3ca7b135.449c16be.b1c res2=00000001 errno=0
+func=rred op1=4335cba8.9af1f855 result=bc9b5ebd.e2aae00a.af8 res2=00000002 errno=0
+func=rred op1=43368e64.82549db1 result=bcb987f9.93a37b64.b0a res2=00000003 errno=0
+func=rred op1=43456a4a.a740a5a7 result=3c9403ac.a68d4d72.b40 res2=00000003 errno=0
+func=rred op1=43462d06.8ea34b03 result=bcc02fd4.862719b3.ae4 res2=00000001 errno=0
+func=rred op1=4355399b.ad67fc50 result=3cbcb220.6e3f6a1b.5ec res2=00000001 errno=0
+func=rred op1=43559af9.a1194efe result=bca15ce7.8f643951.558 res2=00000003 errno=0
+func=rred op1=436020a0.243f2d03 result=bd107cfa.a6b87368.66d res2=00000003 errno=0
+func=rred op1=436fd669.841bfa78 result=3cd58598.52af8f94.871 res2=00000003 errno=0
+func=rred op1=43701be3.bbe6a693 result=3ca6aa71.bdb66194.129 res2=00000003 errno=0
+func=rred op1=437ae960.8c734e12 result=bc981eba.c224221d.30f res2=00000001 errno=0
+func=rred op1=4388422d.16c64e88 result=bcc460be.e7a8bd94.fba res2=00000001 errno=0
+func=rred op1=438d9094.02204d9c result=3cb0a2c3.0d2d590c.c65 res2=00000003 errno=0
+func=rred op1=439995c6.d19cce4d result=bcca686d.9831c61c.47e res2=00000003 errno=0
+func=rred op1=439c3cfa.4749cdd7 result=3c924d96.b06d1ff8.b77 res2=00000001 errno=0
+func=rred op1=43a4d8d5.46c1ba70 result=bc9defde.d3db2441.aa6 res2=00000003 errno=0
+func=rred op1=43a62c6f.01983a35 result=3cc8f424.93c40593.298 res2=00000001 errno=0
+func=rred op1=43b1d08f.a3e8f09f result=3cb9c98e.6563e909.221 res2=00000001 errno=0
+func=rred op1=43bf453f.ea2297a8 result=bcb673e7.1ee45b31.3fd res2=00000001 errno=0
+func=rred op1=43c706c4.f5995f3b result=3cc60b92.8ae88480.ecc res2=00000001 errno=0
+func=rred op1=43ca0f0a.9872290c result=bcc2b5eb.4468f6a9.0a8 res2=00000003 errno=0
+func=rred op1=43d23dba.9de98322 result=bcca31e2.f95fbfb9.752 res2=00000001 errno=0
+func=rred op1=43ded814.f0220525 result=3cd06e98.c32f6db4.9cc res2=00000003 errno=0
+func=rred op1=43e0f02d.497d677b result=bcd852e5.0c220d75.5a7 res2=00000003 errno=0
+func=rred op1=43ed8a87.9bb5e97e result=3ce15e17.b9ce46d6.aa2 res2=00000003 errno=0
+func=rred op1=43fa7f3b.c5a7ed9e result=3c90e54c.54604e37.48c res2=00000001 errno=0
+func=rred op1=43fbccc9.1a140945 result=bca57d38.a9aafd26.060 res2=00000003 errno=0
+func=rred op1=44012845.e01849c4 result=bcd56592.599e564d.cb4 res2=00000001 errno=0
+func=rred op1=440fed89.adf33e83 result=3ce80966.46cd6286.6ea res2=00000003 errno=0
+func=rred op1=441338a6.2a07e463 result=3cc54dec.0991af75.908 res2=00000003 errno=0
+func=rred op1=44148633.7e74000a result=bcb143e5.9492e998.33d res2=00000003 errno=0
+func=rred op1=44203c22.066ded99 result=3cc9873f.1ea9c303.62b res2=00000001 errno=0
+func=rred op1=442782b7.a20df6d4 result=bc57a650.0ca6d83a.c16 res2=00000003 errno=0
+func=rred op1=44360475.9040fb6f result=bcc17332.34ac3748.a95 res2=00000001 errno=0
+func=rred op1=443900f9.b3daf239 result=3cc0b5ff.b4470086.d34 res2=00000003 errno=0
+func=rred op1=4441a209.b98a791f result=bc71bcbc.097d222c.111 res2=00000001 errno=0
+func=rred op1=444ee1a7.9c5e6fee result=3cd09e59.643a59ae.988 res2=00000001 errno=0
+func=rred op1=4453d33f.a4e5ba47 result=bcd1ba25.24d22bd1.599 res2=00000003 errno=0
+func=rred op1=445b322f.9f363361 result=3cd03fc0.2407be4d.ad8 res2=00000001 errno=0
+func=rred op1=4462baa4.af3819b3 result=bcd2480b.051e14e2.ba2 res2=00000001 errno=0
+func=rred op1=446c4aca.94e3d3f5 result=3ccea682.071273b6.c3e res2=00000003 errno=0
+func=rred op1=44722e57.34614969 result=bcd363d6.c5b5e705.7b3 res2=00000001 errno=0
+func=rred op1=447cd718.0fbaa43f result=3ccaf485.851861ed.95a res2=00000003 errno=0
+func=rred op1=4481e830.76f5e144 result=bcd59b6e.46e58b4a.fd5 res2=00000001 errno=0
+func=rred op1=448d1d3e.cd260c64 result=3cc3908c.81243e5b.393 res2=00000003 errno=0
+func=rred op1=4494b574.0c81ec0c result=bcdb8502.4a0f4159.adb res2=00000001 errno=0
+func=rred op1=449a4ffb.379a019c result=3caef591.eb4348f7.621 res2=00000003 errno=0
+func=rred op1=44a308ab.84507e83 result=bca0570e.2e0a677e.20b res2=00000003 errno=0
+func=rred op1=44abb69d.02600700 result=3cd76f3e.be8ca77a.258 res2=00000001 errno=0
+func=rred op1=44b3bbfc.69b38135 result=3cc7382d.707276b9.899 res2=00000001 errno=0
+func=rred op1=44b99caa.5236feea result=bc6b88a7.0d18604d.f4e res2=00000001 errno=0
+func=rred op1=44c36253.f701ffdc result=3cbe194c.b2da85f4.f27 res2=00000003 errno=0
+func=rred op1=44cfd700.ad6bfdf8 result=bcc0c530.ca3ec8ff.588 res2=00000001 errno=0
+func=rred op1=44d67f7f.249c7f63 result=3cbc60c2.4208fff0.132 res2=00000001 errno=0
+func=rred op1=44dcb9d5.7fd17e71 result=bcc1a176.02a78c01.c83 res2=00000003 errno=0
+func=rred op1=44e4c415.54767ef3 result=bcc27dbb.3b104f04.37d res2=00000001 errno=0
+func=rred op1=44ee753f.4ff77ee1 result=3cb73722.ef946de1.754 res2=00000003 errno=0
+func=rred op1=44f0c935.3ec8ff34 result=bcc43645.abe1d509.172 res2=00000001 errno=0
+func=rred op1=44f5a1ca.3c897f2b result=3cb3c60e.0df161d7.b6a res2=00000003 errno=0
+func=rred op1=4501380f.b2d27f50 result=3ca9c7c8.95569388.72d res2=00000003 errno=0
+func=rred op1=450e0664.dbedfec5 result=bc6c0de7.7c1ccc58.206 res2=00000003 errno=0
+func=rred op1=45156a5d.0284bf1d result=bcad4985.84da2d13.76e res2=00000003 errno=0
+func=rred op1=4519d417.8c3bbef8 result=3cc355d6.7000eea6.562 res2=00000001 errno=0
+func=rred op1=45258613.9f871f24 result=3cd01cdd.5d561c35.47c res2=00000003 errno=0
+func=rred op1=4529b860.ef395ef1 result=bcb065a1.3a2ee34f.3d7 res2=00000001 errno=0
+func=rred op1=45335f11.a92ccf3a result=3cdd00c1.a80165f9.813 res2=00000003 errno=0
+func=rred op1=453bdf62.e593aedb result=bcb3e75e.29b27cda.418 res2=00000001 errno=0
+func=rred op1=4540248e.b7a5575b result=3ce82b4c.0c012a4f.eba res2=00000001 errno=0
+func=rred op1=454f19e5.d71b26ba result=bc7230f7.3631c67d.6c6 res2=00000003 errno=0
+func=rred op1=4550a073.e6babb52 result=3cb8a4b9.21f37720.9c1 res2=00000001 errno=0
+func=rred op1=455f95cb.06308ab1 result=bcf6c562.684e566a.dcc res2=00000001 errno=0
+func=rred op1=4566c9ab.e3bdc911 result=bcbd30f6.ef7fe8bf.f72 res2=00000003 errno=0
+func=rred op1=4567dd2c.deeaf106 result=3cb65e9a.3b2d3e50.ee8 res2=00000003 errno=0
+func=rred op1=45732b4f.67a5ae37 result=bcbf7715.d646218f.a4b res2=00000001 errno=0
+func=rred op1=457b7b89.5b030be0 result=3cb1d25c.6da0ccb1.936 res2=00000003 errno=0
+func=rred op1=45815c21.2999a0ca result=bcc201a9.d1e94997.7fe res2=00000001 errno=0
+func=rred op1=458d4ab7.990f194d result=3ca173c1.a50fd2e5.ba7 res2=00000003 errno=0
+func=rred op1=45949ca7.044248e8 result=3ccabb8a.a471330a.5d2 res2=00000001 errno=0
+func=rred op1=45966bd5.424e5655 result=bc57a6b2.243e72f6.3c8 res2=00000003 errno=0
+func=rred op1=45a2fc64.16edf4d9 result=bcb28f91.fec2c049.455 res2=00000003 errno=0
+func=rred op1=45a9db46.6daeb7d1 result=3cb11526.dc7ed919.e18 res2=00000001 errno=0
+func=rred op1=45b4b41c.ac9e2597 result=bcb34cc7.8fe4b3e0.f73 res2=00000001 errno=0
+func=rred op1=45b8238d.d7fe8713 result=3cb057f1.4b5ce582.2fa res2=00000003 errno=0
+func=rred op1=45c58ff8.f7763df6 result=bcb4c732.b2289b10.5b0 res2=00000001 errno=0
+func=rred op1=45c747b1.8d266eb4 result=3cadbb0c.5231fca5.97b res2=00000003 errno=0
+func=rred op1=45d0cb02.87a3c994 result=3cec973b.699452d4.b6a res2=00000003 errno=0
+func=rred op1=45df7c19.28594492 result=bcd87e94.3c6edaa5.0df res2=00000001 errno=0
+func=rred op1=45e099e8.df04baa8 result=bcbab0df.3b3837cd.ea2 res2=00000001 errno=0
+func=rred op1=45ec3dc1.a597f202 result=3c885168.b7ce26bd.6cd res2=00000003 errno=0
+func=rred op1=45f3f0cd.361594ae result=3cc0629c.b495e0be.a2a res2=00000001 errno=0
+func=rred op1=45feb8c9.b1d0b3a9 result=bcc92bc8.afbb5562.135 res2=00000001 errno=0
+func=rred op1=4602455b.0a8d27ab result=bcb49c85.0d44ae1e.8ef res2=00000003 errno=0
+func=rred op1=46081747.6dd6c358 result=3cc36cc9.cb8fa596.504 res2=00000003 errno=0
+func=rred op1=461a2a84.89b75aad result=3cc98123.f9832f45.ab7 res2=00000003 errno=0
+func=rred op1=461e50fe.c1788957 result=bc82fbb4.1b508883.ea8 res2=00000001 errno=0
+func=rred op1=462637ef.ca22412c result=3ca3927b.b0fa049c.723 res2=00000001 errno=0
+func=rred op1=46284b2c.e602d881 result=bcc5cc40.4ef9b6a6.cd9 res2=00000003 errno=0
+func=rred op1=46333506.dc6768c1 result=bcb34717.e6254690.2e5 res2=00000003 errno=0
+func=rred op1=46393ad8.b7dd1997 result=3ccd3607.a40ca7e4.895 res2=00000001 errno=0
+func=rred op1=4640a9f3.d799b0e1 result=3cbd5bb9.897706ea.ab4 res2=00000003 errno=0
+func=rred op1=4648c302.ceeff90c result=bcbcc4f1.f3cd8ad2.239 res2=00000003 errno=0
+func=rred op1=4651ef7d.5a008cd1 result=bca264ec.85a70c6b.62d res2=00000001 errno=0
+func=rred op1=46577d79.4c891d1c result=3ca4c00a.dc4cfccd.819 res2=00000003 errno=0
+func=rred op1=46614cb8.98cd1ed9 result=3cc8c27e.680d43cf.d29 res2=00000003 errno=0
+func=rred op1=466dae3a.00451b5f result=bca009ce.2f011c09.440 res2=00000001 errno=0
+func=rred op1=46719e1a.f966d5d5 result=3cbf2010.4a737b34.426 res2=00000001 errno=0
+func=rred op1=4677cedb.ad22d418 result=bcba69d3.9d279a70.04d res2=00000003 errno=0
+func=rred op1=4681c6cc.29b3b153 result=bc96a723.036a768a.0cd res2=00000001 errno=0
+func=rred op1=4687a62a.7cd5f89a result=3cae2c84.36e4be55.fcc res2=00000003 errno=0
+func=rred op1=4697ba83.14fc6659 result=bcc2deb2.8f6e6ada.859 res2=00000001 errno=0
+func=rred op1=469d99e1.681eada0 result=3c8e1584.cde91f2f.bfd res2=00000001 errno=0
+func=rred op1=46a4c0a7.9f580bd6 result=bcc8887b.5049087d.08d res2=00000003 errno=0
+func=rred op1=46aaa005.f27a531d result=3cc0f79a.6850f11d.fa6 res2=00000003 errno=0
+func=rred op1=46b63369.0e170238 result=3ca69023.9a6ed763.cfd res2=00000003 errno=0
+func=rred op1=46b92d44.83bb5cbb result=bcc4c5ca.b68be497.10d res2=00000001 errno=0
+func=rred op1=46c2802c.e1132c84 result=3cb2cd73.00b1b37d.d7e res2=00000001 errno=0
+func=rred op1=46cce080.b0bf326f result=bcd3d51e.901c9b9d.92d res2=00000003 errno=0
+func=rred op1=46d0a68e.ca9141aa result=3cc0ec1a.b3d3218a.dbe res2=00000001 errno=0
+func=rred op1=46deba1e.c7411d49 result=bce35cc8.7ce4f720.d3d res2=00000003 errno=0
+func=rred op1=46e1935d.d5d23717 result=3cd1dcc6.da426a84.59e res2=00000003 errno=0
+func=rred op1=46efa6ed.d28212b6 result=bcf3209d.734924e2.745 res2=00000003 errno=0
+func=rred op1=46f08cd7.a0a0848c result=3d01ca31.09f250f8.489 res2=00000003 errno=0
+func=rred op1=46ff8d36.a8915598 result=bce645cc.592e7133.8ac res2=00000001 errno=0
+func=rred op1=4709f380.d013367b result=bca97010.b9e2bc2b.6e6 res2=00000001 errno=0
+func=rred op1=470ae04f.db542be8 result=3c8295d0.50198c11.45b res2=00000001 errno=0
+func=rred op1=47103695.0f6cf63b result=3cd724d2.1cefa3c4.5a0 res2=00000001 errno=0
+func=rred op1=471ffd30.63b5a107 result=bcf07c97.d1f28842.744 res2=00000003 errno=0
+func=rred op1=47233b6c.d93e2b81 result=bcca996d.bee454ec.82c res2=00000003 errno=0
+func=rred op1=4724283b.e47f20ee result=3c9be0b8.78265219.e89 res2=00000003 errno=0
+func=rred op1=4730cc31.e9149b71 result=3ca73b44.641fef15.972 res2=00000001 errno=0
+func=rred op1=473d4f8a.cb7dbbf8 result=bcd8db62.3761efca.e43 res2=00000001 errno=0
+func=rred op1=4742f09e.6c6a58e6 result=3ce23c82.34b8f3aa.d7e res2=00000003 errno=0
+func=rred op1=474f73f7.4ed3796d result=bcd30c91.1e59f405.7e6 res2=00000003 errno=0
+func=rred op1=47503063.2d0a376d result=3ce48f3c.3ebc252d.009 res2=00000003 errno=0
+func=rred op1=475ed828.92c91569 result=bcc13097.e2972a77.8e6 res2=00000001 errno=0
+func=rred op1=47647623.428452f0 result=bc9a01dd.34200b54.d0a res2=00000001 errno=0
+func=rred op1=4767d22d.3deed86d result=3ca82ab2.06231278.232 res2=00000001 errno=0
+func=rred op1=4770f325.98173472 result=3cd0f5b2.7cd78b5b.f8b res2=00000001 errno=0
+func=rred op1=477eb134.e3c67c68 result=bcb38165.e718087f.9c7 res2=00000003 errno=0
+func=rred op1=478993ac.132567ac result=bcc0412a.40940715.026 res2=00000001 errno=0
+func=rred op1=478cefb6.0e8fed29 result=3cc4ea76.5f9f110d.891 res2=00000001 errno=0
+func=rred op1=4791e75e.da33c892 result=bcc6c1a1.8d9c09ea.369 res2=00000003 errno=0
+func=rred op1=479f7e7a.76e07787 result=3cd34a58.8c5d1058.3c0 res2=00000003 errno=0
+func=rred op1=47a09ffc.a60b8363 result=bcd52183.ba5a0934.e98 res2=00000001 errno=0
+func=rred op1=47ae3718.42b83258 result=3ce41a67.75fe10b2.e28 res2=00000001 errno=0
+func=rred op1=47be7426.933f5760 result=3c932031.dcc10668.c29 res2=00000001 errno=0
+func=rred op1=47bfbb88.c7679c8f result=bca071c4.45bf8820.6f5 res2=00000003 errno=0
+func=rred op1=47c08175.7dc7f0df result=bcb539d0.bcefc9ba.a00 res2=00000001 errno=0
+func=rred op1=47cf9d01.9f240a0b result=3cf2c6ca.6a2f1417.388 res2=00000003 errno=0
+func=rred op1=47d6d71c.ee6f8188 result=3cacb04a.cb21899d.23d res2=00000003 errno=0
+func=rred op1=47d81e7f.2297c6b7 result=bcc2d5ca.8157a8ed.87a res2=00000003 errno=0
+func=rred op1=47e30898.1c07969c result=3cb7e83e.53f14802.f33 res2=00000001 errno=0
+func=rred op1=47ebed03.f4ffb1a3 result=bcd1a3c7.638b9886.fb8 res2=00000003 errno=0
+func=rred op1=47f12155.b2d3a126 result=3cc58438.18592735.dae res2=00000001 errno=0
+func=rred op1=47fdd446.5e33a719 result=bce10ac5.d4a59053.b57 res2=00000003 errno=0
+func=rred op1=48002db4.7e39a66b result=3cd45234.fa8d16cf.4eb res2=00000001 errno=0
+func=rred op1=480ec7e7.92cda1d4 result=bcf0be45.0d328c3a.126 res2=00000003 errno=0
+func=rred op1=481003d3.fe728131 result=3d023bbc.3c6ccd6b.0d8 res2=00000003 errno=0
+func=rred op1=481f91a8.47a07755 result=bcda54aa.3fb00349.ac1 res2=00000001 errno=0
+func=rred op1=482504ca.c51f1eaf result=bc40cb60.4d34f341.25c res2=00000003 errno=0
+func=rred op1=4825f86b.f9b9196a result=3cb2fe9b.1c269c82.404 res2=00000003 errno=0
+func=rred op1=4830b1fd.38786d17 result=3cef101e.2ea65d2d.6be res2=00000003 errno=0
+func=rred op1=483f0d5f.8d61b0a9 result=bcb384f6.1e90441c.497 res2=00000001 errno=0
+func=rred op1=48400080.60fdd5b2 result=3cb2bb6d.9af1c8b5.3ba res2=00000001 errno=0
+func=rred op1=484a0915.294067ac result=bcb3c823.9fc517e9.4e0 res2=00000003 errno=0
+func=rred op1=485208d4.f8c17cd3 result=bccd25da.6d3dfc43.ebe res2=00000001 errno=0
+func=rred op1=485d050a.f59e0988 result=3cb1aeb7.961e7981.295 res2=00000001 errno=0
+func=rred op1=486682c5.ab4def9d result=3ccb92c9.66010575.d05 res2=00000003 errno=0
+func=rred op1=486b8710.0f6f389a result=bcb5e18f.a96bb651.72c res2=00000003 errno=0
+func=rred op1=487445cd.5207b638 result=bcceb8eb.747af312.077 res2=00000001 errno=0
+func=rred op1=487c460d.8286a111 result=3caaf7bf.05a27961.bfb res2=00000001 errno=0
+func=rred op1=48816429.666b5d7e result=bcba1467.bcb8f321.bc3 res2=00000003 errno=0
+func=rred op1=4888a56c.23d2dfe0 result=3ca2920e.df07ffc1.2cd res2=00000001 errno=0
+func=rred op1=489393f8.cf50f252 result=3cd400f9.71ff7979.4ee res2=00000001 errno=0
+func=rred op1=489db6df.7854cd6e result=bcc56fe4.04f6f331.710 res2=00000003 errno=0
+func=rred op1=48a27c11.1ade27e8 result=3cbbdb16.4e8bffa1.c34 res2=00000003 errno=0
+func=rred op1=48ab2e25.ce13d6a7 result=bcb84db9.2ae5e6a1.b52 res2=00000001 errno=0
+func=rred op1=48b590be.9f5883e4 result=3cd03fcd.0326ffc9.073 res2=00000003 errno=0
+func=rred op1=48be42d3.528e32a3 result=bcc3a935.7323e6b1.69f res2=00000003 errno=0
+func=rred op1=48c0f1ba.58a0f9ea result=3cd988d4.72aaffa9.9da res2=00000003 errno=0
+func=rred op1=48cfcd2a.14cb60a1 result=bcd156f3.9742e6b9.445 res2=00000003 errno=0
+func=rred op1=48d02c8e.f78262eb result=3ce85fb3.84ba7fad.8ad res2=00000001 errno=0
+func=rred op1=48df07fe.b3acc9a2 result=bce28014.853366b5.572 res2=00000001 errno=0
+func=rred op1=48e4e82f.01ac85ca result=bcb2023c.10633762.7f2 res2=00000003 errno=0
+func=rred op1=48e5ad5a.62cb1cc9 result=3c61fa59.d4990bd5.b60 res2=00000001 errno=0
+func=rred op1=48f09d72.89cafadd result=3cf171eb.1e01cc4b.04e res2=00000003 errno=0
+func=rred op1=48ff5c46.8282c8af result=bccb035a.1894d313.bec res2=00000001 errno=0
+func=rred op1=490010b8.f1d0afd7 result=bcb0e296.7319a6a5.23c res2=00000001 errno=0
+func=rred op1=490b49fb.d3c589bb result=3cb5612c.e83fe99a.914 res2=00000003 errno=0
+func=rred op1=4912df09.aa4de650 result=bcad4696.710d0a54.da1 res2=00000001 errno=0
+func=rred op1=49187bab.1b485342 result=3cb7a078.22d30b15.480 res2=00000003 errno=0
+func=rred op1=4921da76.fe9e9693 result=3cd909ff.b6618ae5.2c8 res2=00000003 errno=0
+func=rred op1=492f1cdf.37f20ff1 result=bc969879.38e7fcfe.480 res2=00000001 errno=0
+func=rred op1=493796cc.14e15fe4 result=bcd24c1e.06a82675.084 res2=00000001 errno=0
+func=rred op1=493a651c.cd5e965d result=3c8ab874.e094355a.481 res2=00000001 errno=0
+func=rred op1=4948093b.9814d993 result=3cb55168.70ab9280.ff0 res2=00000001 errno=0
+func=rred op1=494cc0fe.02a85327 result=bc9fd4b8.0185df4f.6c0 res2=00000003 errno=0
+func=rred op1=4959372c.32b9b7f8 result=3cbbff85.a8d09fd7.911 res2=00000003 errno=0
+func=rred op1=495b930d.680374c2 result=bc74710c.83c6a7d4.8f7 res2=00000001 errno=0
+func=rred op1=49602567.e94b772b result=bccdea1e.d52b3f93.7e8 res2=00000001 errno=0
+func=rred op1=496fed0f.46de3bfb result=3ceccbf0.25f66265.deb res2=00000003 errno=0
+func=rred op1=49741751.c0b0285f result=3cb97164.1857cadc.ff2 res2=00000001 errno=0
+func=rred op1=49754542.5b5506c4 result=bcc08de4.64e124e6.5a7 res2=00000001 errno=0
+func=rred op1=49886c27.e1ac3dc3 result=bcc31c05.f559f9e0.ec6 res2=00000001 errno=0
+func=rred op1=498eb9f2.ee5aabc1 result=3cb1c6ff.66ed4bed.495 res2=00000003 errno=0
+func=rred op1=49931ad7.4ad6fc12 result=bcc5aa27.85d2cedb.7e5 res2=00000001 errno=0
+func=rred op1=499641bc.d12e3311 result=3ca95578.8bf743f0.4b0 res2=00000003 errno=0
+func=rred op1=49a205a1.c297f6b9 result=3c8391b0.20c2706e.ee3 res2=00000003 errno=0
+func=rred op1=49afcf28.7699b11a result=bcb1fed6.7fae59c6.b1b res2=00000003 errno=0
+func=rred op1=49b423af.49e314e5 result=3cbbc7ae.900f91fe.28c res2=00000001 errno=0
+func=rred op1=49bdb11a.ef4e92ee result=bccd7077.c39dd4b7.e84 res2=00000003 errno=0
+func=rred op1=49c0f69a.fef267a3 result=bcaa34d4.eefb7b55.ec4 res2=00000001 errno=0
+func=rred op1=49c314a8.863d85cf result=3cc0560d.4c20170c.f22 res2=00000003 errno=0
+func=rred op1=49d17e1e.60c52f2e result=bc8a8c93.38e42b9b.f82 res2=00000001 errno=0
+func=rred op1=49d28d25.246abe44 result=3cc53a79.5450b328.adb res2=00000003 errno=0
+func=rred op1=49ea3d2d.9127c6c5 result=bca3e96e.6aab20b4.fa1 res2=00000003 errno=0
+func=rred op1=49eac4b0.f2fa8e50 result=3cc1e8e6.ed342db5.2eb res2=00000001 errno=0
+func=rred op1=49f599e4.480d1734 result=bccf2f30.89a64383.2ac res2=00000003 errno=0
+func=rred op1=49fee076.da427656 result=3cb68b84.3df6459c.615 res2=00000001 errno=0
+func=rred op1=4a038c01.54692331 result=bcd2e92a.abefa735.146 res2=00000003 errno=0
+func=rred op1=4a082f4a.9d83d2c2 result=3ca28a75.43085f9c.ca8 res2=00000001 errno=0
+func=rred op1=4a14d6b4.7f2480f8 result=bcb14758.975ffbcd.92d res2=00000001 errno=0
+func=rred op1=4a1b87e0.bbe3248c result=3ccb2e21.8eb85d83.93f res2=00000003 errno=0
+func=rred op1=4a2682ff.8e5429dd result=3c7431ca.ba863cf3.7b4 res2=00000003 errno=0
+func=rred op1=4a2f420e.beb6c174 result=bcc9eb04.e30ff9b4.5c4 res2=00000003 errno=0
+func=rred op1=4a314d52.6e8b099f result=3cb3cd91.eeb0c36c.024 res2=00000001 errno=0
+func=rred op1=4a3bb8ac.ae1d4a1b result=bcad823e.801e685e.46e res2=00000003 errno=0
+func=rred op1=4a43e828.fe6f99be result=3cb653cb.46018b0a.71a res2=00000003 errno=0
+func=rred op1=4a491dd6.1e38b9fc result=bca875cb.d17cd921.681 res2=00000001 errno=0
+func=rred op1=4a51c498.2ee57d3c result=bcd45612.118f96f1.bfe res2=00000001 errno=0
+func=rred op1=4a5ddc3d.7da7669d result=3cd0bed8.74812847.d53 res2=00000001 errno=0
+func=rred op1=4a62d660.96aa8b7d result=bcc25858.dd1da2d9.0e1 res2=00000003 errno=0
+func=rred op1=4a6cca75.15e2585c result=3c9fdb93.471f418b.1cd res2=00000001 errno=0
+func=rred op1=4a74acb0.127f5aad result=bcb07ee6.ffb508be.a0d res2=00000003 errno=0
+func=rred op1=4a7ea0c4.91b7278c result=3cd23411.861448da.c97 res2=00000003 errno=0
+func=rred op1=4a8597d7.d069c245 result=3cb7e4ae.75577128.55a res2=00000003 errno=0
+func=rred op1=4a8bdf4d.57f7f0c4 result=bcb906e9.2da2411a.7a8 res2=00000003 errno=0
+func=rred op1=4a952243.f1748e79 result=bca2323f.142540a9.d82 res2=00000001 errno=0
+func=rred op1=4a9c54e1.36ed2490 result=3c9b52a8.65f401c2.897 res2=00000003 errno=0
+func=rred op1=4aa55d0d.e0ef285f result=3cc3581e.b04e20fd.df9 res2=00000003 errno=0
+func=rred op1=4aac1a17.47728aaa result=bcc59c94.20e3c0e2.295 res2=00000001 errno=0
+func=rred op1=4ab53fa8.e931db6c result=3cb47dfe.4c770151.e71 res2=00000001 errno=0
+func=rred op1=4abc377c.3f2fd79d result=bcbd8fd4.0ecd80e3.0de res2=00000003 errno=0
+func=rred op1=4ac1b50c.c25436da result=3cc113a9.3fb88119.95e res2=00000003 errno=0
+func=rred op1=4acfc218.660d7c2f result=bcca257f.020f00aa.bcb res2=00000001 errno=0
+func=rred op1=4ad37a5a.d5c30923 result=3cd2c8d3.c617c135.be8 res2=00000001 errno=0
+func=rred op1=4addfcca.529ea9e6 result=bcdbdaa9.886e40c6.e54 res2=00000003 errno=0
+func=rred op1=4aed28d5.c4c5e73b result=bc810024.4f47e08b.78e res2=00000003 errno=0
+func=rred op1=4aeeee23.d834b984 result=3ca7129f.5222099f.ab4 res2=00000001 errno=0
+func=rred op1=4af13c5f.ff892f0b result=3cc36dfc.07828349.2f9 res2=00000001 errno=0
+func=rred op1=4afe7577.1569b1b5 result=bcea697f.934c202c.ea9 res2=00000003 errno=0
+func=rred op1=4b056d4c.ceb8b8da result=bcb40961.d0b4f515.921 res2=00000003 errno=0
+func=rred op1=4b07329a.e2278b23 result=3cc14df7.7d998737.c07 res2=00000003 errno=0
+func=rred op1=4b12722f.5d698ace result=3c8849ec.0b68a450.c98 res2=00000001 errno=0
+func=rred op1=4b18686a.4007e6e6 result=bcd4cbb1.31103a38.186 res2=00000003 errno=0
+func=rred op1=4b23efbe.161121d4 result=bcc284c3.0ffe6ad0.857 res2=00000003 errno=0
+func=rred op1=4b2bab47.0c1e5035 result=3ca23771.088e7b3c.972 res2=00000003 errno=0
+func=rred op1=4b31b368.0115bf4b result=3ccba07b.9445a86e.d11 res2=00000003 errno=0
+func=rred op1=4b3c6a0e.68721bb8 result=bcb8e490.1a488378.a63 res2=00000003 errno=0
+func=rred op1=4b46af57.869a07c0 result=3cd25e1a.0c467306.8e5 res2=00000001 errno=0
+func=rred op1=4b476e1e.e2edd343 result=bca97f34.292862a0.82d res2=00000003 errno=0
+func=rred op1=4b50539b.48d14c55 result=bc635481.dbfbe4fb.940 res2=00000003 errno=0
+func=rred op1=4b598cb2.f78611bc result=3cb7af47.fc88c528.ece res2=00000003 errno=0
+func=rred op1=4b63e0dd.15df8fcc result=bcba19d8.380841c8.5f7 res2=00000001 errno=0
+func=rred op1=4b6d19f4.c4945533 result=3cb679ff.dec906d9.33a res2=00000001 errno=0
+func=rred op1=4b76b6c8.06b2d0c4 result=3cb544b7.c1094889.7a6 res2=00000003 errno=0
+func=rred op1=4b7a4409.d3c1143b result=bcbc8468.7387be67.d1f res2=00000001 errno=0
+func=rred op1=4b854bd2.8e493048 result=bcbeeef8.af073b07.447 res2=00000001 errno=0
+func=rred op1=4b8baeff.4c2ab4b7 result=3cb06f97.4a0a4f4a.956 res2=00000003 errno=0
+func=rred op1=4b96014d.4a7e0086 result=3ca734ed.a616ac17.60d res2=00000003 errno=0
+func=rred op1=4b9af984.8ff5e479 result=bcc44c9c.ce8296c2.873 res2=00000001 errno=0
+func=rred op1=4ba0ae58.a6ebb474 result=3ccb11f3.2a8ef38f.52a res2=00000001 errno=0
+func=rred op1=4bab5441.ee104c98 result=bc9ee82c.23c23bbf.8e6 res2=00000003 errno=0
+func=rred op1=4bb8aac7.9c47268f result=3caef5c5.3a4c3a4e.fa7 res2=00000001 errno=0
+func=rred op1=4bbdfdbc.3fd972a1 result=bcc73187.60742c73.85d res2=00000003 errno=0
+func=rred op1=4bc47f31.728c3972 result=bcb72e21.1ad1accf.aad res2=00000001 errno=0
+func=rred op1=4bcf7fd8.17cb39b5 result=3cb73bba.315bab5f.16e res2=00000001 errno=0
+func=rred op1=4bd114a9.34ca2fdf result=bcc3511b.96596557.b90 res2=00000003 errno=0
+func=rred op1=4bdc154f.da093022 result=3ccb18bf.b5d3f2d7.08a res2=00000003 errno=0
+func=rred op1=4be84a40.a64ab4ca result=3c9f54f4.d812303a.ef0 res2=00000001 errno=0
+func=rred op1=4bebb4c8.e40cbe5d result=bc9e7b63.6f724744.2dc res2=00000003 errno=0
+func=rred op1=4bf2fa30.cea96d8b result=bccafd8d.88bff5b8.308 res2=00000001 errno=0
+func=rred op1=4bfd9a50.7debfc09 result=3cd55403.fa6486ea.d40 res2=00000003 errno=0
+func=rred op1=4c00826c.5dd702ce result=3ccb33f1.e2e7eff5.e0d res2=00000003 errno=0
+func=rred op1=4c03ecf4.9b990c61 result=bc9da1d2.06d25e4d.6c7 res2=00000003 errno=0
+func=rred op1=4c10090a.775f3363 result=3ca0840b.d4a90114.38d res2=00000001 errno=0
+func=rred op1=4c17d0de.bfd2e55f result=bcc2f1eb.f8936f6b.c47 res2=00000003 errno=0
+func=rred op1=4c21faff.897c1fe2 result=bc9a3b8c.6452ba72.673 res2=00000003 errno=0
+func=rred op1=4c2e201f.dca17a47 result=3ccc0d83.4b87d8ec.a22 res2=00000003 errno=0
+func=rred op1=4c39068a.3c1d4354 result=3cba7934.903d538b.d7e res2=00000003 errno=0
+func=rred op1=4c3af87f.4e3a2fd3 result=bcb3aca9.4b3e0bd5.cd6 res2=00000001 errno=0
+func=rred op1=4c4772b9.f4e99e1a result=bcd3bc13.5638b21c.299 res2=00000001 errno=0
+func=rred op1=4c4e7e44.a78ac18c result=3c4ed415.f54c8cb8.572 res2=00000003 errno=0
+func=rred op1=4c583ca2.188370b7 result=bcb9fde4.38682158.f68 res2=00000003 errno=0
+func=rred op1=4c5bc267.71d40270 result=3cca9808.a632a018.903 res2=00000001 errno=0
+func=rred op1=4c66deb3.7da81129 result=3c671f10.77f9698a.416 res2=00000001 errno=0
+func=rred op1=4c6fdc33.4266211a result=bcc9df10.2272d4cc.3e3 res2=00000001 errno=0
+func=rred op1=4c762fbc.303a6162 result=3ccb1358.fe07d24b.719 res2=00000001 errno=0
+func=rred op1=4c7f2d3b.f4f87153 result=bcc963bf.ca9da299.5cd res2=00000001 errno=0
+func=rred op1=4c82b76f.41ffe114 result=3ccb8ea9.55dd047e.52f res2=00000001 errno=0
+func=rred op1=4c8b05f7.b950413e result=bcc8aac7.46ddd74d.0ac res2=00000003 errno=0
+func=rred op1=4c90fb48.cae2a0ed result=3ccc854a.058768e4.15a res2=00000001 errno=0
+func=rred op1=4c9cc21e.306d8165 result=bcc6bd85.e7890e81.855 res2=00000003 errno=0
+func=rred op1=4ca3ecfe.2445590b result=3ccf692c.14869615.5dd res2=00000001 errno=0
+func=rred op1=4ca9d068.d70ac947 result=bcc3d9a3.d889e150.3d2 res2=00000003 errno=0
+func=rred op1=4cb565d8.d0f6b51a result=3cd29878.1942783b.f71 res2=00000001 errno=0
+func=rred op1=4cbff71f.543c1d9b result=bcb46eb9.f7c3eaad.43d res2=00000003 errno=0
+func=rred op1=4cc3cb58.3f0f66ff result=bca97368.f4e18efe.5c0 res2=00000003 errno=0
+func=rred op1=4ccb6ae9.68f21762 result=3c8582b4.01abf6e7.ec9 res2=00000003 errno=0
+func=rred op1=4cd55505.de5bbc14 result=3cc0c236.3ac105ca.aa6 res2=00000003 errno=0
+func=rred op1=4cd9e13b.c9a5c24d result=bccacb94.34fc4e6c.dad res2=00000001 errno=0
+func=rred op1=4ce85ff7.a3a6e9bb result=3cc3728c.baf684a7.a7f res2=00000001 errno=0
+func=rred op1=4cee75db.2e3d4509 result=bcb16265.74411267.634 res2=00000003 errno=0
+func=rred op1=4cf30ab6.2c0ffab6 result=3cc622e3.3b2c0384.a58 res2=00000003 errno=0
+func=rred op1=4cf615a7.f15b285d result=bca80370.e7ac295a.d04 res2=00000001 errno=0
+func=rred op1=4d01e58e.52ea1a07 result=bc7405e7.30019397.1d4 res2=00000001 errno=0
+func=rred op1=4d0f9b03.076325b8 result=3cb44255.8eabddae.7ac res2=00000001 errno=0
+func=rred op1=4d13fd9b.2222a132 result=bcb943cf.5aac4294.421 res2=00000003 errno=0
+func=rred op1=4d1d82f6.382a9e8d result=3ccfa3de.c901e5bf.2a0 res2=00000001 errno=0
+func=rred op1=4d29cc4f.14c2e375 result=3cae81b7.8556f191.66f res2=00000001 errno=0
+func=rred op1=4d2be45b.e3fb6aa0 result=bcbe4549.26aca77a.096 res2=00000003 errno=0
+func=rred op1=4d35d8ee.b3d67ebe result=3ca47ec3.ed5627c5.d85 res2=00000001 errno=0
+func=rred op1=4d3fd7bc.44e7cf57 result=bcc4241e.5f56b8a2.cc0 res2=00000003 errno=0
+func=rred op1=4d42d338.1bc408cd result=3cd6d22e.0c56a2a7.35d res2=00000001 errno=0
+func=rred op1=4d4cd205.acd55966 result=bca38d0a.72acff68.623 res2=00000001 errno=0
+func=rred op1=4d556219.cf69875b result=bcd19445.e1abf3aa.10f res2=00000003 errno=0
+func=rred op1=4d59557a.3055ec12 result=3ca5707d.67ff5023.4e7 res2=00000003 errno=0
+func=rred op1=4d679734.72163568 result=3cc9dae3.4755fbce.abf res2=00000003 errno=0
+func=rred op1=4d6b13bf.ee95a2bc result=bca1a997.7d5aaead.75e res2=00000001 errno=0
+func=rred op1=4d7a349d.0f75c767 result=3ca93763.52a3f199.271 res2=00000003 errno=0
+func=rred op1=4d7bf2e2.cdb57e11 result=bcc7f770.5203ab13.bfa res2=00000001 errno=0
+func=rred op1=4d836fad.13d05eb8 result=3cc10617.88a8a477.f10 res2=00000001 errno=0
+func=rred op1=4d844ecf.f2f03a0d result=bcba7e63.3c080604.30d res2=00000003 errno=0
+func=rred op1=4d907cc6.858d980b result=3cb06297.93f69a42.6c1 res2=00000003 errno=0
+func=rred op1=4d9741b6.813300ba result=bc746ffe.964146b0.9c5 res2=00000001 errno=0
+func=rred op1=4da265cb.3c3ee90c result=bcc24d17.720cb8e2.fac res2=00000001 errno=0
+func=rred op1=4dac1da1.c6271868 result=3cbf7e2f.3e892019.ce7 res2=00000003 errno=0
+func=rred op1=4db4d3c0.deb8f4e3 result=bcc39417.5b70cd4e.048 res2=00000003 errno=0
+func=rred op1=4db9afac.23ad0c91 result=3cbcf02f.6bc0f743.bae res2=00000001 errno=0
+func=rred op1=4dc03a4e.0fa93aa0 result=bcc4db17.44d4e1b9.0e5 res2=00000001 errno=0
+func=rred op1=4dce491e.f2bcc6d4 result=3cb5462f.f3687cc1.804 res2=00000003 errno=0
+func=rred op1=4dd3be02.486e1dad result=bcc9f716.ea653365.356 res2=00000001 errno=0
+func=rred op1=4ddac56a.b9f7e3c7 result=3ca61c61.508fb2d2.644 res2=00000003 errno=0
+func=rred op1=4de33322.fd48b212 result=3c6ac62b.a4e6c21c.7f8 res2=00000003 errno=0
+func=rred op1=4deed3fe.3de2326f result=bcb399cd.391a109f.b85 res2=00000003 errno=0
+func=rred op1=4df53a6c.bf3dd966 result=bcc404e5.e7adaba8.2a5 res2=00000003 errno=0
+func=rred op1=4dfcccb4.7bed0b1b result=3c8414a0.bbad1195.5fa res2=00000001 errno=0
+func=rred op1=4e022f7e.1c4e1e68 result=3cc68779.ff234dda.d64 res2=00000003 errno=0
+func=rred op1=4e0dd059.5ce79ec5 result=bcc25883.2d5f3f86.626 res2=00000003 errno=0
+func=rred op1=4e12b150.8ccb683d result=3cc833dc.b971b9fc.9e4 res2=00000003 errno=0
+func=rred op1=4e1d4e86.ec6a54f0 result=bcbfabde.2bd33aa7.6cd res2=00000001 errno=0
+func=rred op1=4e27bf02.845c39ac result=3ccd3904.e85cfe61.f62 res2=00000003 errno=0
+func=rred op1=4e2840d4.f4d98381 result=bcb8fa53.42998a20.4cf res2=00000001 errno=0
+func=rred op1=4e357912.c0d275df result=3cd1f547.e8cb5774.8b0 res2=00000003 errno=0
+func=rred op1=4e3a86c4.b863474e result=bc9396ca.1bb1e22b.b53 res2=00000001 errno=0
+func=rred op1=4e46dcf3.dad5fcb0 result=3cb5e079.1dfa4991.923 res2=00000001 errno=0
+func=rred op1=4e4e3095.95f091ec result=bcc4bba1.9cd615de.a3b res2=00000003 errno=0
+func=rred op1=4e58b1dc.499ca1ff result=3ca82a28.2042b0f7.6f3 res2=00000003 errno=0
+func=rred op1=4e5c5bad.2729ec9d result=bcc9a154.23c28e69.910 res2=00000001 errno=0
+func=rred op1=4e62fa9f.52e722d3 result=3c824d78.12433b2e.e82 res2=00000001 errno=0
+func=rred op1=4e64cf87.c1adc822 result=bcce8706.aaaf06f4.7e5 res2=00000003 errno=0
+func=rred op1=4e701f00.d78c633d result=bcb14d1b.19697ac5.d83 res2=00000001 errno=0
+func=rred op1=4e75d63d.ce41e269 result=3cba73d7.228b185d.4c3 res2=00000003 errno=0
+func=rred op1=4e818cd0.1539c308 result=bca9737a.29b157f4.3c4 res2=00000003 errno=0
+func=rred op1=4e84686e.9094829e result=3cbf0735.271be729.064 res2=00000001 errno=0
+func=rred op1=4e9a5338.1fd6a48c result=bcc3169b.9f4501f7.2d3 res2=00000001 errno=0
+func=rred op1=4e9bc107.5d840457 result=3c964eeb.f5aa3cd3.27f res2=00000003 errno=0
+func=rred op1=4ea5f004.1a8833ca result=bccfd058.b41dadf1.4b6 res2=00000003 errno=0
+func=rred op1=4ea75dd3.58359395 result=3cb7e133.0fadca63.b21 res2=00000003 errno=0
+func=rred op1=4eb3be6a.17e0fb69 result=bcdca1e9.6ee782f2.c3d res2=00000003 errno=0
+func=rred op1=4ebdf2a1.602b3cb8 result=3ca32a5d.c1a321b2.139 res2=00000003 errno=0
+func=rred op1=4ec12aea.b2bcd6bd result=bcafbc96.91bf8e36.650 res2=00000001 errno=0
+func=rred op1=4ecfc256.005588ce result=3ce6ae8d.33939848.90e res2=00000001 errno=0
+func=rred op1=4ed675f9.08206d8a result=3cbcbf8c.a274b28b.1d6 res2=00000001 errno=0
+func=rred op1=4ed8a793.0ac7a5eb result=bcb62767.b0edfd5d.5b3 res2=00000001 errno=0
+func=rred op1=4ee2b7a4.dc1b05f3 result=3cc7f4f5.320bea1e.987 res2=00000003 errno=0
+func=rred op1=4eec65e7.36cd0d82 result=bcc15cd0.408534f0.d65 res2=00000001 errno=0
+func=rred op1=4ef1f147.c76bee58 result=bcaf1e85.7ece905f.320 res2=00000003 errno=0
+func=rred op1=4ef5af9b.f37155ef result=3c8cd8d8.11decc13.d49 res2=00000001 errno=0
+func=rred op1=4f00754c.3bc0c65a result=3cce8d1a.23929f4c.5aa res2=00000003 errno=0
+func=rred op1=4f0ea83f.d7274d1b result=bca0b219.75df2a55.47b res2=00000001 errno=0
+func=rred op1=4f11334a.01965a59 result=3cbdfbae.c856ae39.835 res2=00000001 errno=0
+func=rred op1=4f1a2bed.e54c5185 result=bc722d6b.677e225a.eb6 res2=00000003 errno=0
+func=rred op1=4f27edc4.ec5ed3ba result=3caa932a.a4ef07c8.772 res2=00000003 errno=0
+func=rred op1=4f2c6a16.de39cf50 result=bcb1d4f0.2c570c7a.f67 res2=00000001 errno=0
+func=rred op1=4f307334.680a6573 result=bcc879ba.d592ce6d.144 res2=00000003 errno=0
+func=rred op1=4f3f6855.70b34201 result=3cd98672.bd40eb1a.c5b res2=00000001 errno=0
+func=rred op1=4f431168.2dbdddb1 result=3ca17c74.f12ff69b.017 res2=00000003 errno=0
+func=rred op1=413d10a4.f0adcc4f result=3fe87fe6.30304a38.943 res2=00000000 error=0
+func=rred op1=413dba61.a2c03b33 result=3fe0b7a6.a6a685cf.8d6 res2=00000003 error=0
+func=rred op1=c13a34ec.768d711d result=3fe5b7b8.a1db2f4c.b12 res2=00000003 error=0
+func=rred op1=c13cb161.35c98a0f result=3fd67e4f.059466c9.c6f res2=00000001 error=0
+func=rred op1=c13c38d1.7027b607 result=bfdd0737.0b906a40.52b res2=00000002 error=0
+func=rred op1=c13ef602.452f3f79 result=3fe36561.56e3f603.3f7 res2=00000001 error=0
+func=rred op1=c13d6289.355ffec1 result=3fd89d90.7d0bce31.6f3 res2=00000001 error=0
+func=rred op1=413a0a72.b8d35b21 result=3fca0190.f80f3eb6.40a res2=00000002 error=0
+func=rred op1=413cb6dc.3281c1d3 result=bfb5dc53.6f66760b.40a res2=00000000 error=0
+func=rred op1=c13b2097.5e434fcb result=bfe4dc84.b351e6a4.9f6 res2=00000000 error=0
+func=rred op1=c139f416.e781b5a7 result=bfd7826d.074f358e.b0d res2=00000002 error=0
diff --git a/test/testcases/directed/rred3.tst b/test/testcases/directed/rred3.tst
new file mode 100644
index 0000000..8967eb2
--- /dev/null
+++ b/test/testcases/directed/rred3.tst
@@ -0,0 +1,505 @@
+; rred3.tst
+;
+; Copyright (c) 1999-2018, Arm Limited.
+; SPDX-License-Identifier: MIT
+
+func=rred op1=4f454f91.26ab5b7c result=bccabf68.428292b8.71a res2=00000003 errno=0
+func=rred op1=4f569eab.0985179b result=bc561ece.c9c577fd.3e9 res2=00000003 errno=0
+func=rred op1=4f5b7b07.c8260da4 result=3cd61dee.99d944a9.b99 res2=00000001 errno=0
+func=rred op1=4f64d809.9ba17aa6 result=3cb123f9.b608e0bb.0c7 res2=00000001 errno=0
+func=rred op1=4f68654c.7768b490 result=bcb285e6.a2a5383a.e06 res2=00000003 errno=0
+func=rred op1=4f71868a.855f3127 result=bcdf60e1.eb2be0c7.29c res2=00000001 errno=0
+func=rred op1=4f7f440e.697237f9 result=3cc9b5f6.910d5118.92b res2=00000003 errno=0
+func=rred op1=4f808557.ebaaea77 result=3caf8419.92d91276.712 res2=00000001 errno=0
+func=rred op1=4f8cb7fe.275f44bf result=bcb549c0.7bdde73a.883 res2=00000003 errno=0
+func=rred op1=4f939201.7a980109 result=3ca9fc65.e067b477.218 res2=00000001 errno=0
+func=rred op1=4f99ab54.98722e2d result=bcb80d9a.5516963a.300 res2=00000003 errno=0
+func=rred op1=4fa51856.420e8c52 result=3c9dd9fc.f709f0f1.047 res2=00000001 errno=0
+func=rred op1=4fa824ff.d0fba2e4 result=bcbd954e.0787f439.7fb res2=00000003 errno=0
+func=rred op1=4fb0a57e.3ee1734d result=bce19716.baece8b3.584 res2=00000001 errno=0
+func=rred op1=4fbfa481.6315d27b result=3cb6637d.b94774b4.c35 res2=00000003 errno=0
+func=rred op1=4fc0956b.15462ee2 result=bcad509f.1805f781.fae res2=00000001 errno=0
+func=rred op1=4fcb2196.364d750b result=3c512bbb.e07f2de1.317 res2=00000003 errno=0
+func=rred op1=4fd2d6e0.abaa5d9a result=3cae635a.d60dea60.0e0 res2=00000001 errno=0
+func=rred op1=4fd8e020.9fe94653 result=bcc5fc77.520479a1.7c3 res2=00000003 errno=0
+func=rred op1=4fe1b625.e078463e result=bcac3de3.59fe04a3.e7d res2=00000003 errno=0
+func=rred op1=4fec4251.017f8c67 result=3cc6ca84.208a6fc8.0a8 res2=00000003 errno=0
+func=rred op1=4ff24683.461151ec result=3cb04469.290ee80e.1a1 res2=00000001 errno=0
+func=rred op1=4ffa9138.d0b4695d result=bcc52e6a.837e837a.ede res2=00000001 errno=0
+func=rred op1=5001fe54.9344cc15 result=bca7f2f4.61de392b.9b7 res2=00000003 errno=0
+func=rred op1=500b69c4.e919fae2 result=3cc8669d.bd965c15.272 res2=00000003 errno=0
+func=rred op1=50168ff5.64c92090 result=bc9eba2c.e33d4476.056 res2=00000003 errno=0
+func=rred op1=501fb337.07d1c986 result=3cb8da47.194e7efe.b2d res2=00000001 errno=0
+func=rred op1=50246b3c.556d393e result=3cccb18c.b5b6278d.738 res2=00000003 errno=0
+func=rred op1=502d464f.45a95c5d result=bccbca39.fe45e1ba.5c2 res2=00000003 errno=0
+func=rred op1=5030ebf8.0b96d86c result=bcb70ba1.aa6df358.841 res2=00000001 errno=0
+func=rred op1=50357d98.dd1b2ce7 result=3cc50301.7ce6d66f.f22 res2=00000001 errno=0
+func=rred op1=5043bdf6.b82ffc7e result=bccae2e7.46d59be7.44b res2=00000001 errno=0
+func=rred op1=504df394.e2e6991d result=3cce8032.2496b333.a24 res2=00000003 errno=0
+func=rred op1=505254f7.61e36a75 result=bcd8f744.78a1c79f.e46 res2=00000003 errno=0
+func=rred op1=505f5c94.39332b26 result=3cdc948f.5662deec.41f res2=00000001 errno=0
+func=rred op1=50698d45.78b193d2 result=3c9b1a80.f8d4304f.d3d res2=00000003 errno=0
+func=rred op1=506af644.cefe25db result=bca12cec.66d32c4e.1b8 res2=00000001 errno=0
+func=rred op1=507101a0.bf3e8004 result=bcd559f9.9ae0b053.86d res2=00000003 errno=0
+func=rred op1=507f46eb.858b838e result=3ce5bed8.255a2f51.3f3 res2=00000001 errno=0
+func=rred op1=50827574.6f5ee5d9 result=3cc98706.ceee3458.f22 res2=00000001 errno=0
+func=rred op1=5083de73.c5ab77e2 result=bca4cc98.513c4074.4d1 res2=00000001 errno=0
+func=rred op1=5096b5dc.9f2e85da result=3cb0b434.d0361015.ad4 res2=00000001 errno=0
+func=rred op1=509dcdad.a88133d3 result=bcbf32e4.79da60ae.73a res2=00000003 errno=0
+func=rred op1=50a54a28.326cfede result=bc90618e.0418c17a.7f3 res2=00000003 errno=0
+func=rred op1=50a82191.0bf00cd6 result=3cd1ba4d.b0779c2d.553 res2=00000001 errno=0
+func=rred op1=50b60002.68cdc25c result=3cbd5006.1f65efcc.bab res2=00000001 errno=0
+func=rred op1=50bfef3c.4ba37e4d result=bca89255.06252237.bed res2=00000001 errno=0
+func=rred op1=50c4ef3b.173c9d1f result=bccaf12d.92c58902.3cc res2=00000001 errno=0
+func=rred op1=50c5a515.4d9d609d result=3cb51f3f.1d598f0f.7b2 res2=00000003 errno=0
+func=rred op1=50d02514.b369f006 result=3ca9dcf0.369a5ca4.771 res2=00000001 errno=0
+func=rred op1=50daca28.cca06f75 result=bc8b98af.465c9942.1d6 res2=00000001 errno=0
+func=rred op1=50e2b79e.72eb7772 result=bcb3d4a3.ece454a2.c2e res2=00000001 errno=0
+func=rred op1=50e8379f.0d1ee809 result=3cc365b4.28f3c57b.594 res2=00000003 errno=0
+func=rred op1=50f16e59.932ab3bc result=3c982131.26d82006.d0b res2=00000003 errno=0
+func=rred op1=50fc136d.ac61332b result=bccdbef5.e3567ef4.245 res2=00000003 errno=0
+func=rred op1=510212fc.030b1597 result=bcc0d07d.c80950a1.e8c res2=00000001 errno=0
+func=rred op1=510a2586.5cc00d9a result=3cb218e4.dd221805.1c8 res2=00000001 errno=0
+func=rred op1=5115c9ef.f7f560ab result=3cbe297d.708e2808.84e res2=00000003 errno=0
+func=rred op1=511f25bf.316b1c64 result=bcc89489.21819541.435 res2=00000003 errno=0
+func=rred op1=512349d3.8d9fd946 result=3ce235ba.dbcc7553.b93 res2=00000001 errno=0
+func=rred op1=512ca5a2.c71594ff result=bca9ee91.117df4f0.9b1 res2=00000001 errno=0
+func=rred op1=5130809c.95f020f7 result=bc6cd5fe.aa5d4e9c.a57 res2=00000003 errno=0
+func=rred op1=5134dc32.fabacde6 result=3cb73a81.31853591.eb8 res2=00000003 errno=0
+func=rred op1=5146931f.ae82dafb result=bcbad541.06d0df65.804 res2=00000001 errno=0
+func=rred op1=514aeeb6.134d87ea result=3cb56d21.46df60a8.213 res2=00000001 errno=0
+func=rred op1=515389de.22397df9 result=bcbca2a0.f176b44f.4a9 res2=00000003 errno=0
+func=rred op1=515df7f7.9f96e4ec result=3cb1d261.7193b6d4.8c8 res2=00000001 errno=0
+func=rred op1=5162053d.5c14cf78 result=bcc01eb0.63612f11.6fa res2=00000003 errno=0
+func=rred op1=516f7c98.65bb936d result=3ca539c3.8df8c65a.c65 res2=00000001 errno=0
+func=rred op1=5177fe9a.7dd5da32 result=3c8b3b10.e3287c31.ce6 res2=00000001 errno=0
+func=rred op1=5179833b.43fa88b3 result=bcc75430.0df882b8.990 res2=00000003 errno=0
+func=rred op1=51837d4b.26d0a654 result=3cc38612.7fc63e97.a96 res2=00000003 errno=0
+func=rred op1=518c7fe9.d4db0e10 result=bcb96e9c.8df83f16.6ba res2=00000001 errno=0
+func=rred op1=5195bdf2.d2534043 result=3cc6ed74.9c2b4e1d.e33 res2=00000001 errno=0
+func=rred op1=519a3f42.29587421 result=bcb29fd8.552e2009.f81 res2=00000003 errno=0
+func=rred op1=51a31f47.b421b09d result=bca7a228.38c801fb.08f res2=00000001 errno=0
+func=rred op1=51af1e94.f30c9db6 result=3c7cc745.5303d1b6.2be res2=00000001 errno=0
+func=rred op1=51b6af44.eebd125f result=bcc88862.63602088.ba4 res2=00000003 errno=0
+func=rred op1=51bb8e97.b8713bf4 result=3cbd0785.3858b94d.312 res2=00000001 errno=0
+func=rred op1=51c15749.16d3ffbc result=bcb5d5b3.e397c4df.a63 res2=00000003 errno=0
+func=rred op1=51cd5696.55beecd5 result=3cc05036.f15c99c1.fb5 res2=00000003 errno=0
+func=rred op1=51d672f0.67a29dd8 result=3cc21cab.468cd6dd.5e1 res2=00000001 errno=0
+func=rred op1=51d83aef.04f04eb9 result=bcad47c5.1dada0e4.366 res2=00000003 errno=0
+func=rred op1=51e3e51c.bf3b4eca result=bc9dc844.e8577012.40e res2=00000003 errno=0
+func=rred op1=51eac8c2.ad579dc7 result=3cc94e7c.9b4dcb4a.e90 res2=00000001 errno=0
+func=rred op1=51f981d8.d923f640 result=3cb55534.18edf5b1.9bb res2=00000003 errno=0
+func=rred op1=51fdd7ab.1ed8f62f result=bcb65633.ae41940d.b0a res2=00000001 errno=0
+func=rred op1=520116be.b246fb0f result=bcd08066.dd5c4773.3f4 res2=00000003 errno=0
+func=rred op1=5206b37a.cc2fa285 result=3c99c446.9308f6a1.ed0 res2=00000001 errno=0
+func=rred op1=52105304.95e6a4f5 result=bca0e621.9ed2f4c1.4a5 res2=00000003 errno=0
+func=rred op1=521d13f1.0278a015 result=3cc11bab.b1393881.491 res2=00000001 errno=0
+func=rred op1=5223833f.b10b23bd result=3c91bc49.e86c03c1.456 res2=00000001 errno=0
+func=rred op1=522d75ce.10a8cb22 result=bccb90bb.ab49ef9a.183 res2=00000001 errno=0
+func=rred op1=5231eb22.2378e459 result=bca8ee1e.496fe7a1.f20 res2=00000003 errno=0
+func=rred op1=52351b5d.3e9d6321 result=3cbe3359.0d23f792.3e6 res2=00000001 errno=0
+func=rred op1=5242b730.ea42040b result=bc8cc751.840f8f82.b26 res2=00000001 errno=0
+func=rred op1=52444f4e.77d4436f result=3cc388bf.00acfcb9.708 res2=00000003 errno=0
+func=rred op1=52525129.86dd7432 result=bcbc8708.79f1d992.484 res2=00000003 errno=0
+func=rred op1=52531d38.4da693e4 result=3cac46bf.6fd423a1.de3 res2=00000001 errno=0
+func=rred op1=526c45cd.11154dfd result=bc501242.876d7c1a.84c res2=00000001 errno=0
+func=rred op1=526cabd4.7479ddd6 result=3cc5350f.93df1ab9.66a res2=00000003 errno=0
+func=rred op1=52777e7e.fdaba904 result=bcad47e3.984afb63.868 res2=00000001 errno=0
+func=rred op1=5277e486.611038dd result=3cd1ac37.a5e49645.2ae res2=00000001 errno=0
+func=rred op1=5280868d.923f797b result=3cab459b.475d4be0.35e res2=00000003 errno=0
+func=rred op1=528e7670.6917d88d result=bcd20ca5.3511272d.ca0 res2=00000001 errno=0
+func=rred op1=52919edf.3e40bec3 result=bcc5f5ea.b2383c8a.a4e res2=00000003 errno=0
+func=rred op1=5296662d.51aa63bc result=3ca94352.f66f9c5c.e55 res2=00000003 errno=0
+func=rred op1=52a112b6.68401c1f result=bcb0a63a.1d132d35.13d res2=00000001 errno=0
+func=rred op1=52abb9a4.3b14ab59 result=3cd0cb38.027c997b.b79 res2=00000003 errno=0
+func=rred op1=52b0cca1.fd3fcacd result=3cc2f27e.38d3b545.abf res2=00000001 errno=0
+func=rred op1=52b6ac41.bcaab50e result=bcb4aaca.beee8c3b.b51 res2=00000001 errno=0
+func=rred op1=52c0efac.32bff376 result=3c926220.de044084.c11 res2=00000003 errno=0
+func=rred op1=52cc68d7.469576a6 result=bcd5d0ec.ccced044.012 res2=00000001 errno=0
+func=rred op1=52d3cdf6.f7b55442 result=bcc25e86.a32e042b.1ce res2=00000001 errno=0
+func=rred op1=52d96782.4c1fed31 result=3cab9331.4d0660c7.21a res2=00000001 errno=0
+func=rred op1=52e7f85c.e9a53ccb result=3cd26053.c0992257.ef0 res2=00000003 errno=0
+func=rred op1=52ead6a7.ae9a9d97 result=bcb25aec.6857c7d1.78b res2=00000001 errno=0
+func=rred op1=52f1a73e.e3fd4ba9 result=bca253b7.f2ab4f1e.306 res2=00000003 errno=0
+func=rred op1=52fa1f14.fd5d4564 result=3ca27089.c95d31eb.51c res2=00000003 errno=0
+func=rred op1=53058760.980e9c6d result=3cc6fe43.505b8cff.958 res2=00000003 errno=0
+func=rred op1=530eb6c9.62abee5b result=bca236e6.1bf96c51.0ef res2=00000001 errno=0
+func=rred op1=5313974f.be05f40b result=3cbba8ce.ae0bcae0.fab res2=00000001 errno=0
+func=rred op1=53182f04.23549d02 result=bcbb6f2b.00a80546.b7d res2=00000003 errno=0
+func=rred op1=53229f47.51019fda result=bca1fd42.6e95a6b6.cc1 res2=00000001 errno=0
+func=rred op1=5329270c.9058f133 result=3ca2e3d1.2424bd1f.d78 res2=00000003 errno=0
+func=rred op1=53365f2e.272f729f result=3cd030e1.7b8a7d14.784 res2=00000001 errno=0
+func=rred op1=533beeea.f9826fc7 result=bcbafbe3.a5e07a12.322 res2=00000003 errno=0
+func=rred op1=53413b58.1c6ce090 result=3ca3ca5f.d9b3d388.e2f res2=00000003 errno=0
+func=rred op1=534a8afb.c4edb07d result=bca03025.037779e4.b53 res2=00000001 errno=0
+func=rred op1=5351ed4f.b6b74035 result=bcba1554.f05163a9.26b res2=00000003 errno=0
+func=rred op1=5359d904.2aa350d8 result=3cbdaf8f.c68dbd4d.547 res2=00000001 errno=0
+func=rred op1=53658a2e.238818b4 result=3cc8bcf7.d020c86b.1bb res2=00000003 errno=0
+func=rred op1=536ed9d1.cc08e8a1 result=bcb67b1a.1a150a04.f8e res2=00000003 errno=0
+func=rred op1=537362c3.1ffa7ca2 result=3cd643ab.d4ea4df9.ff5 res2=00000003 errno=0
+func=rred op1=537cb266.c87b4c8f result=bccb6db2.1081fee7.31a res2=00000003 errno=0
+func=rred op1=538027a2.9aa61287 result=3ce28db9.dc189650.54c res2=00000001 errno=0
+func=rred op1=538fed87.4dcfb6aa result=bcd401ce.1ede8f93.dc8 res2=00000003 errno=0
+func=rred op1=53944599.ae031379 result=bc6bb722.955e057c.c77 res2=00000003 errno=0
+func=rred op1=5395594f.2fc9e182 result=3cb2eca6.c508e35c.fcb res2=00000001 errno=0
+func=rred op1=53adde8b.c4213631 result=bcb6638b.17b4a40c.95a res2=00000003 errno=0
+func=rred op1=53aef241.45e8043a result=3cb13134.9bb30305.304 res2=00000003 errno=0
+func=rred op1=53b91212.b91224d5 result=bcb81efd.410a8464.622 res2=00000001 errno=0
+func=rred op1=53ba25c8.3ad8f2de result=3ccb8541.12e264df.94e res2=00000001 errno=0
+func=rred op1=53c1df5d.287b8acb result=3cab74a0.920e84ab.2eb res2=00000003 errno=0
+func=rred op1=53c6abd6.338a9c27 result=bcbb95e1.93b64513.fb1 res2=00000001 errno=0
+func=rred op1=53d3127b.6b3f4f22 result=3c9b321e.8ebf03d9.95f res2=00000003 errno=0
+func=rred op1=53d578b7.f0c6d7d0 result=bcc141d5.1c86e339.967 res2=00000001 errno=0
+func=rred op1=53ec9bb9.20def6b3 result=3cb46596.eb0f42e3.307 res2=00000001 errno=0
+func=rred op1=53edced7.63a2bb0a result=bcb4ea9a.f1ae4486.61f res2=00000003 errno=0
+func=rred op1=53f73d8b.24ad40bf result=3cd2d3b6.03cb130e.637 res2=00000001 errno=0
+func=rred op1=53f870a9.67710516 result=bc9d462e.a93b0a66.5bc res2=00000001 errno=0
+func=rred op1=5405c192.69582a1c result=3cb3e092.e470413f.ff0 res2=00000001 errno=0
+func=rred op1=540b1fc0.6589e010 result=bcc89360.c6d5a5d3.2d6 res2=00000003 errno=0
+func=rred op1=5417191d.e8649799 result=3c94f5ee.3f4af033.448 res2=00000003 errno=0
+func=rred op1=5419c834.e67d7293 result=bccfe4ec.7124686c.c45 res2=00000001 errno=0
+func=rred op1=5421a8b9.4e0e8d12 result=bca2cb37.8995924c.b98 res2=00000001 errno=0
+func=rred op1=542c8982.82baa220 result=3cbe5b8a.0415b959.a14 res2=00000003 errno=0
+func=rred op1=543a7d15.f515d39b result=bcbc30d3.4e605b73.164 res2=00000003 errno=0
+func=rred op1=543fed7a.8f6bde22 result=3ca720a4.f5004e19.cf8 res2=00000001 errno=0
+func=rred op1=5448cb19.eebd359a result=bc9ceb94.3c55acff.470 res2=00000003 errno=0
+func=rred op1=544e3b7e.89134021 result=3cd211d9.a0aae670.0a9 res2=00000003 errno=0
+func=rred op1=545539e9.9e65e156 result=bcc668aa.112047ec.a26 res2=00000003 errno=0
+func=rred op1=545c5c4a.3f1489de result=3cafcb7f.cbd5c5b3.fb9 res2=00000001 errno=0
+func=rred op1=54670281.c6918b78 result=bccda38f.2035b32c.742 res2=00000001 errno=0
+func=rred op1=546a93b2.16e8dfbc result=3c76ff5c.7c00c5a5.a46 res2=00000003 errno=0
+func=rred op1=5479af66.02d30aab result=bcbb7b9e.7495a0a4.ecc res2=00000003 errno=0
+func=rred op1=547b77fe.2afeb4cd result=3cc09dba.c9cae907.2ae res2=00000001 errno=0
+func=rred op1=54830a79.7d18d2bc result=bccc3399.5875a6d2.19e res2=00000003 errno=0
+func=rred op1=5483eec5.912ea7cd result=3c913f85.5d00943c.3b4 res2=00000001 errno=0
+func=rred op1=54910e75.585c765e result=3cd0f9b8.3bbaec1d.c17 res2=00000001 errno=0
+func=rred op1=549d7402.4fbb112b result=bcc7e3b8.013581c3.0b1 res2=00000001 errno=0
+func=rred op1=54a5d113.b7a2ab0d result=3cd3d9a3.cb3b04d2.760 res2=00000001 errno=0
+func=rred op1=54af5650.762f146b result=bcc0b3eb.1a7543ff.47a res2=00000003 errno=0
+func=rred op1=54b4dfec.a468a96d result=3cd82985.227b29e1.84d res2=00000001 errno=0
+func=rred op1=54b9a28b.03aede1c result=bcb02850.d7e9f3c2.540 res2=00000003 errno=0
+func=rred op1=54c37632.0791a6fd result=3c9b5c2e.905b478d.418 res2=00000003 errno=0
+func=rred op1=54cfcee3.ffcc153b result=bcd1de13.c0efa83b.282 res2=00000001 errno=0
+func=rred op1=54d3b27b.cc602765 result=3cd2f548.460648b5.0f6 res2=00000003 errno=0
+func=rred op1=54d9ded4.c87d5e84 result=bc83d1cc.7de27fdd.9a1 res2=00000001 errno=0
+func=rred op1=54e3580d.252a66c9 result=bcc1656d.9fc81bc0.2da res2=00000003 errno=0
+func=rred op1=54e9fcf9.aae49eb8 result=3ccc994b.58396f8b.1b2 res2=00000003 errno=0
+func=rred op1=54f3671f.965e06e3 result=bc9dbab2.bcd3bfcc.671 res2=00000003 errno=0
+func=rred op1=54f9ede7.39b0fe9e result=3cca1f11.c87d1f8f.67e res2=00000001 errno=0
+func=rred op1=55035f96.5dc436d6 result=bcd34118.cb9557bc.f41 res2=00000001 errno=0
+func=rred op1=5509e65e.01172e91 result=3cc52a9e.a9047f98.016 res2=00000001 errno=0
+func=rred op1=55102780.6101730c result=bcd5bb52.5b51a7b8.a76 res2=00000001 errno=0
+func=rred op1=551d1e73.fdd9f25b result=3cb18efd.b4addf5b.023 res2=00000003 errno=0
+func=rred op1=5521cb14.97fca4fe result=3c9e985d.d6f27db0.d4a res2=00000003 errno=0
+func=rred op1=552842c9.ca1bfc9f result=bca8576a.104bc0e2.c9d res2=00000003 errno=0
+func=rred op1=5535d4f4.b03d01c1 result=bcd1e846.a0735802.8cc res2=00000003 errno=0
+func=rred op1=553ab09e.e3faf77d result=3cb6f246.6135de44.9f7 res2=00000001 errno=0
+func=rred op1=554301ff.24ec226d result=3cd37883.921d0736.0f7 res2=00000003 errno=0
+func=rred op1=554979b4.570b7a0e result=bc76523a.f15e29e2.a4f res2=00000003 errno=0
+func=rred op1=5555a264.77840f86 result=3cbd333a.27dc9b12.aa5 res2=00000003 errno=0
+func=rred op1=555d5104.3692e496 result=bcc163e4.721a12c5.a9c res2=00000001 errno=0
+func=rred op1=55678e0c.6747c4ca result=3cba68f2.c9b0d5d6.55b res2=00000001 errno=0
+func=rred op1=556b655c.46cf2f52 result=bcc2c908.212ff563.d41 res2=00000003 errno=0
+func=rred op1=557883e0.5f299f6c result=3cb4d464.0d594b5d.ac8 res2=00000001 errno=0
+func=rred op1=557a6f88.4eed54b0 result=bcc5934f.7f5bbaa0.28b res2=00000003 errno=0
+func=rred op1=5588feca.5b1a8cbd result=3ca3568d.29546cd8.b41 res2=00000001 errno=0
+func=rred op1=5589f49e.52fc675f result=bccb27de.3bb34518.d1f res2=00000003 errno=0
+func=rred op1=5592ddd2.435024e2 result=bc77dd6e.404de84f.86c res2=00000001 errno=0
+func=rred op1=559f1fc2.72e4f498 result=3cc41578.9b56dc1b.304 res2=00000003 errno=0
+func=rred op1=55a5b0d9.513ce227 result=3cd474ee.545813bc.6e6 res2=00000001 errno=0
+func=rred op1=55ac4cbb.64f83753 result=bc91e612.b03a6e3b.a51 res2=00000003 errno=0
+func=rred op1=55b484ca.c83efa2d result=bcc88efd.476577aa.199 res2=00000003 errno=0
+func=rred op1=55baa5c2.e0096208 result=3cc119ca.d34d1f11.3f7 res2=00000003 errno=0
+func=rred op1=55c6c1ca.91acc375 result=3cbc3c3a.1686c40e.9d3 res2=00000003 errno=0
+func=rred op1=55c868c3.169b98c0 result=bccd0881.f3741339.02d res2=00000001 errno=0
+func=rred op1=55d5a34a.acf5ded1 result=bcd17fee.c1c3c6a6.724 res2=00000001 errno=0
+func=rred op1=55d98742.fb527d64 result=3ca4ac4e.cc98aba5.f03 res2=00000003 errno=0
+func=rred op1=55e6328a.9f515123 result=bcab0e8d.b40324f9.1d5 res2=00000003 errno=0
+func=rred op1=55ecdbfb.5753a9a5 result=3ccb6ff2.399974e4.378 res2=00000001 errno=0
+func=rred op1=55f32572.3c7dde0b result=3cbf0276.32e50178.e85 res2=00000001 errno=0
+func=rred op1=55fc945b.5e25f07c result=bcb0b866.4db6cf26.254 res2=00000001 errno=0
+func=rred op1=5604abfe.6de79797 result=3c8f9f43.f70ee3fe.57e res2=00000003 errno=0
+func=rred op1=560e1ae7.8f8faa08 result=bcd6e074.2095712f.940 res2=00000003 errno=0
+func=rred op1=5613e8b8.5532bad1 result=3cd07e35.392af7dc.66e res2=00000001 errno=0
+func=rred op1=561bd115.457113b6 result=bca1a12a.9fe62c4d.1e8 res2=00000003 errno=0
+func=rred op1=56250da1.7a4205fa result=bcc520b0.f5b05a39.6ce res2=00000001 errno=0
+func=rred op1=562b6f72.3916a553 result=3cc437ec.a380fd12.739 res2=00000001 errno=0
+func=rred op1=56314a44.885010b9 result=3c9bfc32.ae516f62.72b res2=00000003 errno=0
+func=rred op1=563f32cf.2b089a94 result=bca5443b.e8a3a0e9.03b res2=00000001 errno=0
+func=rred op1=5642fb21.7b1bd428 result=3cc34f28.51519feb.7a4 res2=00000003 errno=0
+func=rred op1=564d81f2.383cd725 result=bcc6f239.9a0f1487.5f7 res2=00000001 errno=0
+func=rred op1=5657661b.604673ef result=bcbfe659.dcf5715d.859 res2=00000003 errno=0
+func=rred op1=565916f8.5312375e result=3cb15a14.b9ff9eed.f0d res2=00000001 errno=0
+func=rred op1=5664582f.f44b4254 result=bc8f5139.75200fd8.96a res2=00000003 errno=0
+func=rred op1=566dd5c0.b1d92c68 result=3cd2549e.85a89f6c.b59 res2=00000001 errno=0
+func=rred op1=5676b794.23aebcd9 result=3cbeca02.455b3be0.cee res2=00000001 errno=0
+func=rred op1=567e8447.ee70e37e result=bca77ceb.17d80be2.710 res2=00000001 errno=0
+func=rred op1=56896e3b.f15e12e9 result=bcb392c3.e93409e7.5e2 res2=00000003 errno=0
+func=rred op1=568bcda0.20c18d6e result=3cccd4ee.ae093ae3.457 res2=00000001 errno=0
+func=rred op1=56909d77.de101cc7 result=bcda28ec.e2f0a362.db4 res2=00000003 errno=0
+func=rred op1=569d28f4.07993876 result=3cc11679.221d34f2.0cf res2=00000003 errno=0
+func=rred op1=56a8c091.fdf23d65 result=3c86ddc6.78d2d05c.1a6 res2=00000003 errno=0
+func=rred op1=56add69d.fb050dfa result=bca999c7.d6eb5bc1.901 res2=00000003 errno=0
+func=rred op1=56b4015a.fa955792 result=bcc60f0e.b04adedc.af5 res2=00000003 errno=0
+func=rred op1=56bd7fc9.014f2338 result=3ccbc680.4e7f92f3.b5f res2=00000001 errno=0
+func=rred op1=56c3d5f0.7dba6231 result=bc9c55c9.3503e727.05b res2=00000001 errno=0
+func=rred op1=56cdab33.7e2a1899 result=3cbdf338.c613ca25.dbd res2=00000003 errno=0
+func=rred op1=56d1609f.bd9e7497 result=bcc0579d.12162ac5.a8c res2=00000003 errno=0
+func=rred op1=56d64b41.3dd64fcb result=3c9165c3.bca1b991.2f1 res2=00000001 errno=0
+func=rred op1=56e51098.ddc858fe result=bca3a2e7.56b30a5e.6e3 res2=00000003 errno=0
+func=rred op1=56e785e9.9de44698 result=3cbb3737.67fb3ec0.662 res2=00000001 errno=0
+func=rred op1=56f0ad96.4f29fe80 result=3ce5eb3c.76a9c9cf.db6 res2=00000001 errno=0
+func=rred op1=56ff98e5.4cac857d result=bcbd745b.020c8f8d.a54 res2=00000001 errno=0
+func=rred op1=570069c6.d65d3e25 result=3c9e5140.4520d187.dff res2=00000003 errno=0
+func=rred op1=570af213.45416aa4 result=bca81d2e.8ad5abf8.ec6 res2=00000001 errno=0
+func=rred op1=57180156.1184e1d1 result=bcc9aa32.f968755c.a94 res2=00000001 errno=0
+func=rred op1=571de2d0.78fdf377 result=3c88d046.e92c963b.ce3 res2=00000003 errno=0
+func=rred op1=5724358e.73f10ffb result=bcc215e2.e82040fa.b15 res2=00000003 errno=0
+func=rred op1=5727264b.a7ad98ce result=3cb242a8.ffb5fb8b.69b res2=00000001 errno=0
+func=rred op1=57324faa.a5272710 result=bc976a16.2c7ec1b6.0a9 res2=00000003 errno=0
+func=rred op1=573bfcec.aa340a8c result=3cd3b94a.627de7a6.ca6 res2=00000001 errno=0
+func=rred op1=5744bafb.266a5fef result=3cbeaacc.744c46a9.50d res2=00000001 errno=0
+func=rred op1=574b777f.f7baba98 result=bcb18f90.a15f1148.87f res2=00000001 errno=0
+func=rred op1=5756e395.4e70f0d4 result=bcbd449b.b79e7223.8d4 res2=00000003 errno=0
+func=rred op1=57594ee5.cfb429b3 result=3ccbbd89.aebc6e72.8f8 res2=00000001 errno=0
+func=rred op1=576005b5.5082422e result=bcc47cd3.66eee97f.494 res2=00000001 errno=0
+func=rred op1=576b98db.24590e95 result=3cda46e8.4bf48257.2ed res2=00000001 errno=0
+func=rred op1=57712aaf.fad4b49f result=bcd5f374.c9b6d59a.a9f res2=00000001 errno=0
+func=rred op1=577f07cb.235065e8 result=3ce814f6.37c8a02e.1dd res2=00000003 errno=0
+func=rred op1=57808785.0f5c5168 result=bd0043a7.41699ccb.2c1 res2=00000001 errno=0
+func=rred op1=578f899a.e22a7522 result=3cbcc116.86cdb576.a4a res2=00000003 errno=0
+func=rred op1=5790e9c8.1b67ad02 result=3c955c01.693bcf02.685 res2=00000003 errno=0
+func=rred op1=57920ec2.c5ba1f73 result=bcb21315.d22fcdf5.708 res2=00000003 errno=0
+func=rred op1=57a95eac.291b8383 result=3cb00501.0eecdb41.ce3 res2=00000001 errno=0
+func=rred op1=57aa83a6.d36df5f4 result=bcbecf2b.4a10a82a.46f res2=00000001 errno=0
+func=rred op1=57b491bc.cd185f0a result=3cd261cb.8722118b.c5e res2=00000003 errno=0
+func=rred op1=57be2b9b.851ea7fc result=bca2e653.c1a9b24f.bd4 res2=00000001 errno=0
+func=rred op1=57c78ab1.d0432a7f result=3ca7d1af.10cdebb5.136 res2=00000001 errno=0
+func=rred op1=57cc57a1.2c464ef8 result=bcd1c460.1d3d8a5f.1b2 res2=00000003 errno=0
+func=rred op1=57d6a0b4.a3d6fdfd result=bcbc597d.a27e8b77.9be res2=00000003 errno=0
+func=rred op1=57df1598.b18ad47e result=3cacbd0a.5ff2251a.699 res2=00000003 errno=0
+func=rred op1=57e715b3.3a0d143e result=bc921f3a.46c27f0a.21c res2=00000001 errno=0
+func=rred op1=57ef8a97.47c0eabf result=3cd43a0d.c4cfa711.c63 res2=00000001 errno=0
+func=rred op1=57f315c0.7e4e341e result=bcc52a3b.0a820231.017 res2=00000001 errno=0
+func=rred op1=57fb15a5.f5cbf45e result=3cb8353b.ce418557.e12 res2=00000003 errno=0
+func=rred op1=580515b9.dc2da42e result=bcc9b209.9c32a1f3.89e res2=00000003 errno=0
+func=rred op1=580915ac.97ec844e result=3cae4b3d.55c08ba5.a08 res2=00000001 errno=0
+func=rred op1=581815af.e8fccc46 result=bc87ccdc.df11c9ba.8bf res2=00000001 errno=0
+func=rred op1=581a15a9.46dc3c56 result=3ccfc80b.23b1a841.494 res2=00000003 errno=0
+func=rred op1=582795b1.9184f042 result=bcc39c08.14b39ba5.ca8 res2=00000001 errno=0
+func=rred op1=582895ae.4074a84a result=3cbb51a1.b9de526e.4f0 res2=00000003 errno=0
+func=rred op1=5837d5b0.bd40de44 result=bcc695a3.b095d4dd.1c0 res2=00000003 errno=0
+func=rred op1=583855af.14b8ba48 result=3cb55e6a.8219dfff.ac0 res2=00000001 errno=0
+func=rred op1=5847f5b0.531ed545 result=bccc88da.e85a474b.bf0 res2=00000003 errno=0
+func=rred op1=584835af.7edac347 result=3ca2eff8.2521f644.cc2 res2=00000001 errno=0
+func=rred op1=58522043.b9ac94b5 result=bc837392.e7bf4dd6.ff5 res2=00000001 errno=0
+func=rred op1=585e4b1b.4408f1d9 result=3cc42731.539deb22.3c1 res2=00000003 errno=0
+func=rred op1=58652af9.9c43abfe result=3cb08185.c82a0c89.ec3 res2=00000003 errno=0
+func=rred op1=586b2065.cb93e38f result=bcd27542.3e8b51ba.a0f res2=00000001 errno=0
+func=rred op1=5879ab0a.a537536b result=bcc1fa8c.57f4ad30.75c res2=00000001 errno=0
+func=rred op1=587cb5c0.87ce6ab4 result=3c9b1ef1.51299679.b23 res2=00000003 errno=0
+func=rred op1=5885e5a7.2f71f410 result=bcc6d771.11e480a6.35a res2=00000001 errno=0
+func=rred op1=5888f05d.12090b59 result=3cc3e563.f24f3f59.227 res2=00000001 errno=0
+func=rred op1=58958850.65dad007 result=3cb45734.fcdf30db.45a res2=00000001 errno=0
+func=rred op1=58994db3.dba02f62 result=bcc00fb4.bd9a1b07.c91 res2=00000003 errno=0
+func=rred op1=58a00ee6.99fe5303 result=3cd59753.0761d8c0.bda res2=00000001 errno=0
+func=rred op1=58ab01ba.31b74d0b result=bc9401e0.a82a7e57.7fc res2=00000003 errno=0
+func=rred op1=58b11795.29d573dc result=3ca11e00.fd14574d.f24 res2=00000001 errno=0
+func=rred op1=58bdbe6f.17a58b8d result=bccbd7e9.3bef203c.159 res2=00000003 errno=0
+func=rred op1=58c275ef.9ccc931d result=bcbc90e1.26b4a9fe.78f res2=00000003 errno=0
+func=rred op1=58c9a35f.bec02dca result=3cb9ad01.7b9e82f4.eb7 res2=00000003 errno=0
+func=rred op1=58d55d7a.744ad0d3 result=3cc56581.3c596d21.6ed res2=00000001 errno=0
+func=rred op1=58df479f.7c2caa02 result=bcbf74c0.d1cad108.067 res2=00000001 errno=0
+func=rred op1=58e3e9b5.088bb1f8 result=bcacad7f.a96cf374.284 res2=00000003 errno=0
+func=rred op1=58e82f9a.53010eef result=3c863a09.42eeec9e.f14 res2=00000001 errno=0
+func=rred op1=58f280a5.193092ea result=3ccb10a2.0fcd71be.da8 res2=00000003 errno=0
+func=rred op1=58fdde8f.8cd18af4 result=bcc5821f.bf11b697.1e3 res2=00000001 errno=0
+func=rred op1=5903352d.10de2271 result=3cb973c4.762df009.8cc res2=00000001 errno=0
+func=rred op1=590d2a07.9523fb6d result=bc89cdd9.99f81b54.dbe res2=00000003 errno=0
+func=rred op1=591aacd0.f412852e result=3c9f8d25.b8e1cb93.74a res2=00000003 errno=0
+func=rred op1=591fa73e.363571ac result=bcb4ca36.3b34808f.4b1 res2=00000001 errno=0
+func=rred op1=592250d5.bc2c2f15 result=bcc8bbda.f250ba01.b9b res2=00000003 errno=0
+func=rred op1=592e0e5e.e9d5eec9 result=3ce14bfb.5e0ba4cf.e71 res2=00000001 errno=0
+func=rred op1=5932c301.668528c3 result=3cca2bad.fa0b2611.5fe res2=00000003 errno=0
+func=rred op1=59354038.07969f02 result=bc940e8d.7b0e6b16.431 res2=00000003 errno=0
+func=rred op1=5947f684.7dd49218 result=3cba8982.5a1e30cd.e3e res2=00000003 errno=0
+func=rred op1=594fe054.0b61ee83 result=bcae15d4.3895a0a1.64a res2=00000001 errno=0
+func=rred op1=5953e511.cc77a577 result=bccc4fab.4959e8b7.a44 res2=00000003 errno=0
+func=rred op1=59569b5e.42b5988d result=3cb0823b.9c96fb42.c25 res2=00000001 errno=0
+func=rred op1=59609dbd.23407407 result=3c99ebd3.7c3f16de.833 res2=00000003 errno=0
+func=rred op1=596b3dd9.270bc388 result=bcab2731.37fd4abd.449 res2=00000003 errno=0
+func=rred op1=59739c8d.b2fb064a result=3cc3bfb6.0c1ede1e.92c res2=00000001 errno=0
+func=rred op1=597e3ca9.b6c655cb result=bc63b5db.bbe33dec.159 res2=00000001 errno=0
+func=rred op1=59846e62.dd48d2a6 result=bcc45d64.e9fdf80d.f37 res2=00000001 errno=0
+func=rred op1=59876d33.6d0364e9 result=3ca8b075.c080e2ff.c1d res2=00000003 errno=0
+func=rred op1=599106a7.b8675a35 result=bcd0f87e.c2fe4eb6.4ad res2=00000003 errno=0
+func=rred op1=599ad4ee.91e4dd5a result=3ca639ba.49047b42.3f2 res2=00000001 errno=0
+func=rred op1=59a0d232.6dd3e71e result=bcb00a54.137b0d1c.24f res2=00000003 errno=0
+func=rred op1=59ae0834.6c32e2b4 result=3cdcb30a.c55fa646.cb1 res2=00000001 errno=0
+func=rred op1=59b5d390.7fdc623c result=3c98bd98.d625b898.68c res2=00000001 errno=0
+func=rred op1=59b93b4b.a4bddaad result=bcc80f7e.1d3893aa.377 res2=00000001 errno=0
+func=rred op1=59c352e1.76d824ad result=bcb9e541.f16cac12.2fc res2=00000003 errno=0
+func=rred op1=59c8543f.88e09fcb result=3cc9516d.63c93255.4c4 res2=00000001 errno=0
+func=rred op1=59d05eac.5fe549ad result=3cb28e32.a09c4a72.4e9 res2=00000003 errno=0
+func=rred op1=59d8c7c5.96cf3d3c result=bcc6cd8e.d6a7f4ff.22a res2=00000003 errno=0
+func=rred op1=59e45975.f462f4bc result=3cddf4fa.0bf044f1.dfe res2=00000001 errno=0
+func=rred op1=59ecc28f.2b4ce84b result=bca0fd70.d82eaa33.503 res2=00000001 errno=0
+func=rred op1=59f11bb9.a5a2006d result=3c8f009f.f7dc3994.626 res2=00000003 errno=0
+func=rred op1=59fd7f9c.71099f0b result=bcd5d589.d6e91332.7f9 res2=00000001 errno=0
+func=rred op1=5a06ef24.6877745c result=bcaa3ab9.b2664601.87c res2=00000001 errno=0
+func=rred op1=5a0c6408.886e8ceb result=3cc22eea.698c2718.06d res2=00000001 errno=0
+func=rred op1=5a114afc.f7112e1d result=bccb6c33.43c3c2e6.3e7 res2=00000003 errno=0
+func=rred op1=5a1c934b.d9ddba9b result=3c831799.15d7ce4b.6a7 res2=00000001 errno=0
+func=rred op1=5a21335b.4e599745 result=bcc3ac0b.45ccb481.25d res2=00000003 errno=0
+func=rred op1=5a26d782.bfbfdd84 result=3cb1e343.1ea91693.9e8 res2=00000001 errno=0
+func=rred op1=5a31278a.79fdcbd9 result=bca0aeed.277a5edb.d29 res2=00000003 errno=0
+func=rred op1=5a3c877b.0581ef2f result=3cd3f920.c398626f.18d res2=00000001 errno=0
+func=rred op1=5a46dd6b.29edc33a result=3c73455f.72eb7b7c.bf7 res2=00000003 errno=0
+func=rred op1=5a4c9934.440ba051 result=bcc9a08e.b6ceea25.a1d res2=00000003 errno=0
+func=rred op1=5a512496.44e6d8fe result=3cc27d6e.1a40726f.848 res2=00000001 errno=0
+func=rred op1=5a5c9640.0ef4ad76 result=bcc014c2.2be302ff.ec9 res2=00000003 errno=0
+func=rred op1=5a640100.b76a4e1c result=3cc3b1c4.116f2a27.507 res2=00000003 errno=0
+func=rred op1=5a69b9d5.9c713858 result=bcbdc0d8.69689690.413 res2=00000001 errno=0
+func=rred op1=5a756f35.f0ac08ab result=3cc61a6f.ffcc9996.e86 res2=00000003 errno=0
+func=rred op1=5a784ba0.632f7dc9 result=bcb8ef80.8cadb7b1.115 res2=00000001 errno=0
+func=rred op1=5a806ef5.c2d17524 result=3cc8831b.ee2a0906.805 res2=00000003 errno=0
+func=rred op1=5a8d4be0.910a1150 result=bca4f6f1.ecfa3627.038 res2=00000001 errno=0
+func=rred op1=5a951465.afa156be result=bcd17f4a.7253920d.011 res2=00000003 errno=0
+func=rred op1=5a9a14a5.dd7bea45 result=3ca193cc.f8dcc0d2.7b5 res2=00000001 errno=0
+func=rred op1=5aa2c1ad.b93965f1 result=3cbc0f45.ef59dbe5.fd1 res2=00000001 errno=0
+func=rred op1=5aa5f8e8.6cc78cfc result=bcbf726a.e377513a.855 res2=00000003 errno=0
+func=rred op1=5ab24f6c.5aa64ad2 result=bcca34ae.6838c3b0.c47 res2=00000001 errno=0
+func=rred op1=5abdbe21.ef9d2c6f result=3cb8ac20.fb3c6691.74e res2=00000001 errno=0
+func=rred op1=5ac07aae.5195a9bd result=bcd795d0.2a997ceb.e40 res2=00000001 errno=0
+func=rred op1=5acf92df.f8adcd84 result=3cc36e64.7ffdd907.b40 res2=00000003 errno=0
+func=rred op1=5ad19e2e.056787d7 result=3cb1e5d7.13017be8.647 res2=00000001 errno=0
+func=rred op1=5ad372ec.0e7828ec result=bc8888d6.cfc5d1f4.f86 res2=00000003 errno=0
+func=rred op1=5aeb57a4.0ca39c4d result=3cc05d49.a6051ec9.14f res2=00000001 errno=0
+func=rred op1=5aed2c62.15b43d62 result=bca266a1.1bd45d77.ba4 res2=00000001 errno=0
+func=rred op1=5af67ae9.09059212 result=3cd12190.5c834d58.bcb res2=00000003 errno=0
+func=rred op1=5af84fa7.12163327 result=bcaeab0c.83b74672.367 res2=00000003 errno=0
+func=rred op1=5b01eeed.91317459 result=bcda54e0.ea6d7c14.99e res2=00000001 errno=0
+func=rred op1=5b0eb060.92faf1f5 result=3cc5feb5.5123b1b6.fd4 res2=00000003 errno=0
+func=rred op1=5b10428f.4e05c985 result=bcdeee89.31629372.887 res2=00000003 errno=0
+func=rred op1=5b1b8003.d288928e result=3caaa4bc.3d2039f7.883 res2=00000001 errno=0
+func=rred op1=5b229cbc.ece25382 result=bca66cf1.626b69f2.689 res2=00000001 errno=0
+func=rred op1=5b2f868f.b490c75f result=3cd64231.fecefeb7.4f4 res2=00000003 errno=0
+func=rred op1=5b370e60.5fb57308 result=3caedc87.17d509fc.a7d res2=00000003 errno=0
+func=rred op1=5b3beb1b.63537d43 result=bcc0d1b5.09d08f75.ce6 res2=00000003 errno=0
+func=rred op1=5b44d58e.a64be345 result=bc9bfab7.5a0393d0.529 res2=00000001 errno=0
+func=rred op1=5b494732.191f02cb result=3cd12def.018abe3b.591 res2=00000003 errno=0
+func=rred op1=5b586055.04cfb044 result=bcd29160.7f70c8b2.d39 res2=00000003 errno=0
+func=rred op1=5b5a9926.be394007 result=3c770e7d.ee8bb162.aa3 res2=00000001 errno=0
+func=rred op1=5b67b75a.b24291a6 result=bca918e7.9c321da3.fd4 res2=00000003 errno=0
+func=rred op1=5b6d7af2.ca2fee68 result=3cb25013.49bbfb2a.a93 res2=00000001 errno=0
+func=rred op1=5b719f45.710ea595 result=3cc8964d.30c88293.a88 res2=00000003 errno=0
+func=rred op1=5b7dcf6f.f3767db7 result=bcd8d79a.667d501b.d2e res2=00000001 errno=0
+func=rred op1=5b833a6a.0bad446d result=bc9b2351.49d889e5.505 res2=00000003 errno=0
+func=rred op1=5b861c36.17a3f2ce result=3ccb781c.ee99f8bf.fdc res2=00000003 errno=0
+func=rred op1=5b96e9c8.64f3423a result=3c92f9aa.933ed8e0.042 res2=00000003 errno=0
+func=rred op1=5b9b66b9.0b888f73 result=bcd484e2.c9c31ed9.52f res2=00000001 errno=0
+func=rred op1=5ba2d3a0.e5059cb7 result=3cd37fad.f2efe8b8.a97 res2=00000003 errno=0
+func=rred op1=5baeaf4e.3e26e58a result=bcb664e6.a508d3ad.4f4 res2=00000003 errno=0
+func=rred op1=5bb30705.78597092 result=3cc96db3.40f38c7e.aab res2=00000003 errno=0
+func=rred op1=5bbacc8b.518d13e2 result=bca9d022.b6d2ce7a.9a7 res2=00000001 errno=0
+func=rred op1=5bc8db29.db402b0e result=3c984664.df55c68a.dba res2=00000001 errno=0
+func=rred op1=5bccbdec.c7d9fcb6 result=bcccd8ef.52bd874b.f5e res2=00000003 errno=0
+func=rred op1=5bd7e279.2019b6a4 result=3cc60277.2f2991b1.5f9 res2=00000001 errno=0
+func=rred op1=5bd9d3da.96669f78 result=bcb3be89.7efd5cd7.e38 res2=00000003 errno=0
+func=rred op1=5be85ed1.7dacf0d9 result=3ccc1410.66ff0354.168 res2=00000003 errno=0
+func=rred op1=5be95782.38d36543 result=bc9e6d5c.3d49e649.d6d res2=00000001 errno=0
+func=rred op1=5bf2e28b.9339bd65 result=3c921f6d.8161a6cb.e08 res2=00000003 errno=0
+func=rred op1=5bffcc78.de6d0d21 result=bcc17a9b.ced127fe.677 res2=00000001 errno=0
+func=rred op1=5c061d06.e6069154 result=bca55da5.7c9912e3.e69 res2=00000001 errno=0
+func=rred op1=5c0c15a5.2e0cfefd result=3cd356c2.7f966f54.e2c res2=00000003 errno=0
+func=rred op1=5c11837a.189cf088 result=bcd66a3e.2e907f34.605 res2=00000001 errno=0
+func=rred op1=5c1df10f.063d060f result=3c9dc26b.0c547567.b4e res2=00000001 errno=0
+func=rred op1=5c2095c5.2c84ecff result=bcc0063c.1d72ce2a.ece res2=00000003 errno=0
+func=rred op1=5c2869cd.4cbb61ba result=3cb99008.4476c425.cdb res2=00000001 errno=0
+func=rred op1=5c31bc28.5fdf5532 result=3c90c98b.1f76c507.9cc res2=00000003 errno=0
+func=rred op1=5c37436a.1960f987 result=bcb12b42.b4bb61a1.ff5 res2=00000001 errno=0
+func=rred op1=5c43ec97.a2f2f343 result=bcd4510c.caa1a693.6cc res2=00000003 errno=0
+func=rred op1=5c4a9a3c.8fceffcb result=3ca92e50.af32278b.6b2 res2=00000001 errno=0
+func=rred op1=5c536791.9b165854 result=3ccfdb9c.70434e08.a88 res2=00000003 errno=0
+func=rred op1=5c58eed3.5497fca9 result=bcb5bf5d.11ddaf7e.492 res2=00000003 errno=0
+func=rred op1=5c60e673.c243d3a1 result=bcaab52f.044499f4.f58 res2=00000001 errno=0
+func=rred op1=5c69c487.f2337e3a result=3c8b779c.eaa3c069.0fe res2=00000001 errno=0
+func=rred op1=5c75c058.290969b6 result=3cc28104.ee21010e.2dc res2=00000001 errno=0
+func=rred op1=5c7dc8b7.bb5d92be result=bcb7463b.66f021e7.d39 res2=00000003 errno=0
+func=rred op1=5c87c270.0d9e73f8 result=3cc5eff8.8b75791b.4fb res2=00000003 errno=0
+func=rred op1=5c8bc69f.d6c8887c result=bcb06854.2c4731cd.8f9 res2=00000001 errno=0
+func=rred op1=5c98c37b.ffe8f919 result=3ccccddf.c61e6935.93b res2=00000003 errno=0
+func=rred op1=5c9ac593.e47e035b result=bc85642d.b7aa8cc8.3d0 res2=00000001 errno=0
+func=rred op1=5ca3d3eb.eecbe13c result=3ca61e91.7cb91d37.00a res2=00000001 errno=0
+func=rred op1=5ca4d4f7.e116665d result=bcc89c7e.426acab4.576 res2=00000003 errno=0
+func=rred op1=5cb0db9d.ed1812bd result=bcb5c15f.9a31d4ff.9ed res2=00000003 errno=0
+func=rred op1=5cbdbde1.e631d1da result=3cc096ed.1d8ad5e9.407 res2=00000003 errno=0
+func=rred op1=5cc8c8e6.ea7ed98b result=3ccba635.dbe76484.c0c res2=00000001 errno=0
+func=rred op1=5ccfba8e.e030fbaa result=bca4a9c9.f29bfc59.796 res2=00000001 errno=0
+func=rred op1=5cd4d242.6bcb7624 result=3ca79359.06d63e14.87e res2=00000003 errno=0
+func=rred op1=5cdbc3ea.617d9843 result=bcddde3d.37b39bd8.8e2 res2=00000003 errno=0
+func=rred op1=5cea4668.a5fe38e7 result=bca1c03a.de61ba9e.6ae res2=00000001 errno=0
+func=rred op1=5cef3b63.a1b13136 result=3cc1ae82.c520ae8f.65e res2=00000001 errno=0
+func=rred op1=5cfa06d3.06be53ad result=3ccd782f.488bcd99.a9d res2=00000003 errno=0
+func=rred op1=5cff7af9.40f11670 result=bc97da39.6bda6e50.9bd res2=00000001 errno=0
+func=rred op1=5d04f20d.3b6b68c1 result=3cb19cca.abdfa280.60e res2=00000003 errno=0
+func=rred op1=5d0f9ac4.1091090d result=bcd6276d.8959a33e.832 res2=00000001 errno=0
+func=rred op1=5d179c3a.f0b4d0d4 result=bcb1e3ab.10e3d2bc.74e res2=00000003 errno=0
+func=rred op1=5d1cd0cb.8ba7ae5d result=3cbd4306.fcc8a96c.9ae res2=00000003 errno=0
+func=rred op1=5d23acdb.c896ae06 result=bcbdd0c7.c6d109e4.c2d res2=00000001 errno=0
+func=rred op1=5d28e16c.63898b8f result=3cd01f27.1521fb9b.572 res2=00000001 errno=0
+func=rred op1=5d31b52c.34879c9f result=bccad580.9955bc1a.af5 res2=00000001 errno=0
+func=rred op1=5d3ec87b.1fb6bfc4 result=3cdbc563.660b0287.912 res2=00000001 errno=0
+func=rred op1=5d4016bb.b115b68e result=bcf2de75.8f6ff7ca.323 res2=00000003 errno=0
+func=rred op1=5d4f21ba.3053eb1a result=3caf594f.d184a1b7.aa4 res2=00000001 errno=0
+func=rred op1=5d51888c.ac3906f4 result=bca05b23.06303ae9.8d6 res2=00000001 errno=0
+func=rred op1=5d5ef51a.a805556f result=3cedbaf8.63234ca3.0bc res2=00000003 errno=0
+func=rred op1=5d685523.6e467907 result=3cb72bbe.4e6c8442.e39 res2=00000003 errno=0
+func=rred op1=5d6a4cd3.02558a6e result=bcb888b4.8948585e.542 res2=00000003 errno=0
+func=rred op1=5d75eaaf.d74748b1 result=bcc471eb.c7bc49a3.f0c res2=00000001 errno=0
+func=rred op1=5d7cb746.9954bac4 result=3cc314f5.8ce07588.803 res2=00000003 errno=0
+func=rred op1=5d871fe9.a2c6e0dc result=3c95ce94.3581d4f7.96b res2=00000003 errno=0
+func=rred op1=5d8b820c.cdd52299 result=bca5cefb.f19f8b57.4f7 res2=00000001 errno=0
+func=rred op1=5d94543b.277ff3e8 result=bccdfc73.85b03b34.280 res2=00000003 errno=0
+func=rred op1=5d9e4dbb.491c0f8d result=3cc8889a.9a40eac6.65e res2=00000001 errno=0
+func=rred op1=5da157ef.3a1528a5 result=3cb05aef.28215fb9.b10 res2=00000001 errno=0
+func=rred op1=5da5ba12.65236a62 result=bcc888ce.784fc5f6.425 res2=00000001 errno=0
+func=rred op1=5db20ada.d8e6e3e2 result=3cd9e583.dd990815.df5 res2=00000001 errno=0
+func=rred op1=5dbc34f8.6ca6ddd6 result=bcb05bbe.a05ccc79.229 res2=00000003 errno=0
+func=rred op1=5dc3e276.9f052722 result=3c95cb56.549421f9.d07 res2=00000003 errno=0
+func=rred op1=5dcebf7f.d196dc53 result=bcd72c19.130683d6.a54 res2=00000001 errno=0
+func=rred op1=5dd80bb7.85d6027c result=bcbb44a7.ab949073.d10 res2=00000001 errno=0
+func=rred op1=5dddd3b1.ee87bab3 result=3cb05880.bf6f197b.5c5 res2=00000001 errno=0
+func=rred op1=5de1cdd6.2b9cb975 result=3ccdfad4.953961b5.44d res2=00000001 errno=0
+func=rred op1=5defe852.61f02860 result=bc95e545.5c01b9e8.025 res2=00000001 errno=0
+func=rred op1=5df9e564.807aa7c1 result=3cb05204.fd93b37f.cfe res2=00000001 errno=0
+func=rred op1=5dfbfa04.f3e3156e result=bcce0150.5714c7b0.d15 res2=00000003 errno=0
+func=rred op1=5e01eb4f.e7fe9da9 result=3cc30ead.a913eabc.d02 res2=00000001 errno=0
+func=rred op1=5e07ee3d.c9741e48 result=bcb06bf4.05014b6e.01b res2=00000003 errno=0
+func=rred op1=5e13f133.7d36193c result=bcbb5e96.b3022862.02e res2=00000001 errno=0
+func=rred op1=5e1de26e.ccb8accd result=3ccde761.4fa72fc2.9f7 res2=00000001 errno=0
+func=rred op1=5e21f2ae.571716b6 result=bcc8a1ee.0781f125.029 res2=00000001 errno=0
+func=rred op1=5e2fe0f3.f2d7af53 result=3cdc890c.f9e71424.1f5 res2=00000003 errno=0
+func=rred op1=5e30f36b.c4079573 result=bcd74399.b1c1d586.827 res2=00000001 errno=0
+func=rred op1=5e3ee1b1.5fc82e10 result=3ced3837.24c721f3.5f6 res2=00000001 errno=0
+func=rred op1=5e407779.b20c1158 result=bd0240b0.7732a570.d90 res2=00000003 errno=0
+func=rred op1=5e4f6501.e0dc2b38 result=3ccd4bc7.2315a02d.747 res2=00000001 errno=0
+func=rred op1=5e51b106.168d1822 result=3cad9a07.1c4f9915.c89 res2=00000001 errno=0
+func=rred op1=5e52b048.a99c9965 result=bc9c6107.3767b574.780 res2=00000001 errno=0
+func=rred op1=5e6b88cb.b4e32576 result=3c638ffe.4e7e3a15.09c res2=00000003 errno=0
+func=rred op1=5e6c880e.47f2a6b9 result=bcc59705.62c7c0ff.ae2 res2=00000003 errno=0
+func=rred op1=5e769ce8.e5b81ecc result=3cbe3687.0ec38ae6.70e res2=00000001 errno=0
+func=rred op1=5e779c2b.78c7a00f result=bcccaf47.30a1ae5c.cc2 res2=00000001 errno=0
+func=rred op1=5e8912da.4d4da221 result=3cbf6f86.f3ab6e87.c18 res2=00000003 errno=0
+func=rred op1=5e8dfebd.1c78a8cb result=bcba8b87.600be002.7f1 res2=00000001 errno=0
+func=rred op1=5e936ba0.13df9a6e result=3cc05443.6c49a914.891 res2=00000001 errno=0
+func=rred op1=5e95e191.7b751dc3 result=bcb95287.7b23fc61.2e7 res2=00000003 errno=0
+func=rred op1=5ea77a35.e4615ff2 result=3cc2c643.36197057.2a4 res2=00000001 errno=0
+func=rred op1=5eaf9761.8564eafa result=bcb1fc88.1db4a699.4ad res2=00000003 errno=0
+func=rred op1=5eb98180.cca242b4 result=3cc7aa42.c9b8fedc.6cb res2=00000001 errno=0
+func=rred op1=5ebd9016.9d240838 result=bca06911.eceb131d.8bd res2=00000003 errno=0
+func=rred op1=5ecc8c71.290396d7 result=3ca6b6ea.b011610c.87b res2=00000003 errno=0
+func=rred op1=5ece93bc.11447999 result=bcc616cc.98ef6b60.adc res2=00000001 errno=0
+func=rred op1=5ed5286b.81ba94c9 result=3cbeeb73.a686ea9b.4da res2=00000003 errno=0
+func=rred op1=5ed62c10.f5db062a result=bcb89d9a.e3609cac.51c res2=00000001 errno=0
+func=rred op1=5ee27a0e.22368523 result=bcc48356.6825d7e4.eec res2=00000003 errno=0
diff --git a/test/testcases/directed/rred4.tst b/test/testcases/directed/rred4.tst
new file mode 100644
index 0000000..1b84f45
--- /dev/null
+++ b/test/testcases/directed/rred4.tst
@@ -0,0 +1,504 @@
+; rred4.tst
+;
+; Copyright (c) 1999-2018, Arm Limited.
+; SPDX-License-Identifier: MIT
+
+func=rred op1=5ee8da6e.555f15d0 result=3ccad12f.2b4c25d3.eaa res2=00000001 errno=0
+func=rred op1=5ef7833f.a59d0dfd result=3c919ca2.3f5c493c.c76 res2=00000003 errno=0
+func=rred op1=5efb3542.79418f04 result=bca803d2.ba28019c.b3f res2=00000001 errno=0
+func=rred op1=5f014ca4.10454889 result=bcc66a06.9b751384.b8d res2=00000001 errno=0
+func=rred op1=5f0db9db.3af4d371 result=3ccf3857.bb233823.1c8 res2=00000003 errno=0
+func=rred op1=5f1467f1.daf12b43 result=bcc202de.0b9e0135.86f res2=00000003 errno=0
+func=rred op1=5f1e5090.43ed71be result=3c966ae3.892121b9.b5c res2=00000001 errno=0
+func=rred op1=5f25f598.c0471ca0 result=bcb26919.d7dfb92e.468 res2=00000003 errno=0
+func=rred op1=5f2fde37.2943631b result=3cd035f4.06ca3721.2c0 res2=00000003 errno=0
+func=rred op1=5f3355c3.e3c9e36e result=3cc469fe.b0806d73.fe2 res2=00000001 errno=0
+func=rred op1=5f3a2314.821a472f result=bc9ccea0.4d3ca145.ae7 res2=00000001 errno=0
+func=rred op1=5f44a5ae.52088007 result=3c900726.c505a22d.bd1 res2=00000003 errno=0
+func=rred op1=5f4fa07a.b22c0e57 result=bcc06834.ff3f04e8.8ee res2=00000001 errno=0
+func=rred op1=5f51e6fb.39ff9c73 result=3cba6cad.3a628a45.250 res2=00000003 errno=0
+func=rred op1=5f576461.6a11639b result=bca4cb0c.eab9d02e.cff res2=00000001 errno=0
+func=rred op1=5f634654.c6040e3d result=3cc13820.4e72adae.01c res2=00000001 errno=0
+func=rred op1=5f660507.de0cf1d1 result=bc830f98.96d0b804.4b7 res2=00000003 errno=0
+func=rred op1=5f75555b.180ab8ec result=3cab4a67.6457165a.674 res2=00000003 errno=0
+func=rred op1=5f76b4b4.a40f2ab6 result=bcb72cff.fd93e72f.596 res2=00000001 errno=0
+func=rred op1=5f802813.bc17239e result=bcf18ec6.9cbd007b.734 res2=00000003 errno=0
+func=rred op1=5f8f505b.de0ddc7d result=3cd37073.b19084f9.09f res2=00000003 errno=0
+func=rred op1=5f900004.52080ab1 result=3cc477cd.8b4150c3.cd7 res2=00000001 errno=0
+func=rred op1=5f9b5a5e.a40fa00c result=bc95a993.9294b35c.5f4 res2=00000003 errno=0
+func=rred op1=5fa30286.180a7e41 result=3cb5e002.7fb1e983.4f7 res2=00000001 errno=0
+func=rred op1=5fae5ce0.6a12139c result=bcd1b4ff.5da76cce.858 res2=00000001 errno=0
+func=rred op1=5fb483c6.fb0bb809 result=bcb03f2e.adef8685.477 res2=00000001 errno=0
+func=rred op1=5fb9d91d.c10e6644 result=3cc32ad0.0d5f5317.c39 res2=00000001 errno=0
+func=rred op1=5fc54467.6c8c54ed result=bcd71f64.424c99a5.9d5 res2=00000001 errno=0
+func=rred op1=5fca99be.328f0328 result=3cb0ac0c.8829f2d3.27e res2=00000001 errno=0
+func=rred op1=5fd42376.c24b6997 result=bc93f61c.29ab0224.dd4 res2=00000001 errno=0
+func=rred op1=5fda396d.f9ceb4b6 result=3cd755d3.2f69cfcc.8d8 res2=00000003 errno=0
+func=rred op1=5fe4539e.deab90d0 result=bcd17e90.708a36a7.954 res2=00000001 errno=0
+func=rred op1=5feac9e6.4eef2a61 result=3c9ac3f9.cd51c702.e52 res2=00000003 errno=0
+func=rred op1=5ff776ae.889d49fc result=bc8a507d.0c087a8d.aab res2=00000001 errno=0
+func=rred op1=5ffe1d1e.15410ac6 result=3cbe0e09.6ed2d654.9a8 res2=00000003 errno=0
+func=rred op1=600261c6.d0f265c8 result=3ccfb311.3f935dfd.752 res2=00000001 errno=0
+func=rred op1=600fdece.069a0e95 result=bcc59b23.fa6b89cd.b7f res2=00000001 errno=0
+func=rred op1=60119902.e675f77d result=bca3bc5d.c9065bea.401 res2=00000003 errno=0
+func=rred op1=6014ec3a.acc7d7e2 result=3ccc6901.9e124eab.bfd res2=00000003 errno=0
+func=rred op1=6022de3c.d460b08a result=bcd66da7.e2cbcda2.254 res2=00000003 errno=0
+func=rred op1=602c0f20.3cd9e36e result=3cc28ad2.b98f20b6.9fc res2=00000001 errno=0
+func=rred op1=6039c2e7.62bb96b5 result=3ca58a50.ce2b8dbf.29c res2=00000001 errno=0
+func=rred op1=603fa093.04e2e934 result=bc8318b0.f773b33a.03e res2=00000001 errno=0
+func=rred op1=6045adf5.2498c719 result=bcbcb393.2af6f0f4.eb3 res2=00000001 errno=0
+func=rred op1=604dd7d9.a0de6651 result=3cd1f20d.31d3831c.cfa res2=00000003 errno=0
+func=rred op1=6051dac2.a182dc68 result=3cc6bbdb.dda2c8f2.ca0 res2=00000003 errno=0
+func=rred op1=6057b86e.43aa2ee7 result=bc9ca509.732d8cd7.05d res2=00000003 errno=0
+func=rred op1=6066b331.b4217b00 result=bcd0241a.2cae5147.e5f res2=00000001 errno=0
+func=rred op1=6068bdaa.d332e2ce result=3cc1f5af.9fc5dc24.490 res2=00000003 errno=0
+func=rred op1=607341bd.9b4977cd result=bcd28730.4b9cc7af.267 res2=00000001 errno=0
+func=rred op1=607c2f1e.ec0ae601 result=3cb0d2ae.4818050e.8e2 res2=00000003 errno=0
+func=rred op1=60820ba1.d6a1d027 result=3c9d1957.3178adc6.30f res2=00000003 errno=0
+func=rred op1=6089f3c6.97da8a74 result=bca7a4b6.562b0f90.ef4 res2=00000003 errno=0
+func=rred op1=6094e208.0d25ff87 result=bcc901de.8cfe771e.3fb res2=00000003 errno=0
+func=rred op1=609f0585.228f1561 result=3c85d283.6d3678d5.06c res2=00000001 errno=0
+func=rred op1=60a376d4.f1e3e7d7 result=bcc1bb88.c0a04bac.b37 res2=00000001 errno=0
+func=rred op1=60a88893.7c9872c4 result=3cb146fc.066325fd.b95 res2=00000003 errno=0
+func=rred op1=60b2c13b.6442dbff result=bc9976e9.3f1fa64c.d7c res2=00000001 errno=0
+func=rred op1=60be4feb.94ee0989 result=3cd2de6a.9a552062.86d res2=00000003 errno=0
+func=rred op1=60c8e360.4368f8b0 result=3c922e1d.9b4d4b5d.35e res2=00000001 errno=0
+func=rred op1=60cf6051.e95f9b4d result=bcc55ef2.a2c16625.488 res2=00000001 errno=0
+func=rred op1=60d293d5.00da9909 result=3cc38cbf.b9cccf69.601 res2=00000003 errno=0
+func=rred op1=60df32eb.85f75857 result=bcb4eb61.d84c5375.8a4 res2=00000001 errno=0
+func=rred op1=60e2aa88.328eba84 result=3cab452c.68f3f10b.d0d res2=00000003 errno=0
+func=rred op1=60e8fa13.751d1a2b result=bcc73125.8bb5fce1.310 res2=00000001 errno=0
+func=rred op1=60f5c6f4.3afbd99a result=3cbfd0b3.cfc743e3.1e4 res2=00000003 errno=0
+func=rred op1=60fc167f.7d8a3941 result=bcd60e43.b201282b.5da res2=00000003 errno=0
+func=rred op1=61011c52.2e582af9 result=3cc8ff68.b58a47a0.2a1 res2=00000003 errno=0
+func=rred op1=610da4b5.81c0c8cc result=bce57cd2.c526bdd0.73f res2=00000003 errno=0
+func=rred op1=611049dd.9362d276 result=3cf61b3b.e3a3ae02.7ba res2=00000001 errno=0
+func=rred op1=611feeac.ef388f5f result=bcd1fa3c.d4c33400.bdd res2=00000001 errno=0
+func=rred op1=61256913.865b3e16 result=bca08f17.66fc9079.756 res2=00000003 errno=0
+func=rred op1=6126f749.8a91cda1 result=3ca3cd23.cf9e0640.f65 res2=00000003 errno=0
+func=rred op1=6130ed61.d407dd37 result=3ce1252c.24dd8255.9e8 res2=00000003 errno=0
+func=rred op1=613e8f67.45524d96 result=bcce996f.288ab7b8.4df res2=00000001 errno=0
+func=rred op1=6140d5e9.a6dfb656 result=3ca70b30.383f7c08.774 res2=00000001 errno=0
+func=rred op1=614b8a73.6a0d5561 result=bc9425fd.2b7349d4.e73 res2=00000003 errno=0
+func=rred op1=61531f7e.969d7a36 result=bcb59896.b1d962ee.af3 res2=00000001 errno=0
+func=rred op1=615940de.7a4f9181 result=3cc14864.2a2f9d06.597 res2=00000003 errno=0
+func=rred op1=6161fab4.1ebe9846 result=3c772998.6661919c.80a res2=00000003 errno=0
+func=rred op1=616caf3d.e1ec3751 result=bcd03271.05630a33.036 res2=00000003 errno=0
+func=rred op1=61728d19.5aae093e result=bcc4df49.eea65661.cb3 res2=00000001 errno=0
+func=rred op1=617af80e.2e1de469 result=3c915f32.4cc92d35.607 res2=00000001 errno=0
+func=rred op1=6181b181.80c6dfca result=3cc93716.81d8a1af.235 res2=00000001 errno=0
+func=rred op1=618b4140.cc159ce5 result=bcc1fa16.e1da242e.3b2 res2=00000001 errno=0
+func=rred op1=6191d61a.cfc2bc08 result=3ccc1c49.8ea4d3e2.b36 res2=00000001 errno=0
+func=rred op1=619b1ca7.7d19c0a7 result=bcbb4494.9d4fb1c1.c60 res2=00000003 errno=0
+func=rred op1=61a1e867.7740aa27 result=3cd0f357.d41e9c24.e9c res2=00000001 errno=0
+func=rred op1=61ab0a5a.d59bd288 result=bca3cac4.a10d0918.cb0 res2=00000003 errno=0
+func=rred op1=61b68287.7a2d3567 result=3caa886c.2bb61a20.363 res2=00000003 errno=0
+func=rred op1=61bf922e.310a6fa9 result=bcca6cdf.abfa8fa0.d89 res2=00000001 errno=0
+func=rred op1=61c447c4.2034dde6 result=bcbdb026.f1938da5.309 res2=00000001 errno=0
+func=rred op1=61cd451e.2f942a09 result=3cb0a309.db2f9593.d0b res2=00000001 errno=0
+func=rred op1=61d0e678.c5816395 result=bcc8bd75.c9504b5e.fdd res2=00000003 errno=0
+func=rred op1=61d9e3d2.d4e0afb8 result=3cc595bb.0372d7da.037 res2=00000003 errno=0
+func=rred op1=61e3b480.1fd74c7e result=3c8caf66.265cec13.86e res2=00000003 errno=0
+func=rred op1=61e715cb.7a8ac6cf result=bcb034d7.dc416b96.5a3 res2=00000001 errno=0
+func=rred op1=61f09cd6.c5529ae1 result=bcd2e549.6fda21b8.2ed res2=00000003 errno=0
+func=rred op1=61fd8ec0.2fc2f2bd result=3ca5838c.9cc5b10e.a52 res2=00000001 errno=0
+func=rred op1=6206f0fa.7a736275 result=3cccc194.8d0a12de.e53 res2=00000003 errno=0
+func=rred op1=620a5245.d526dcc6 result=bcb5a7e9.6a1ffea5.61c res2=00000003 errno=0
+func=rred op1=6210659d.452f845a result=3cd02bc0.a8ead830.ab0 res2=00000001 errno=0
+func=rred op1=62170362.fa7f14a2 result=bc9d40d9.5bc6226e.793 res2=00000003 errno=0
+func=rred op1=62255bf1.8d2b3090 result=3cb55f2f.cf6b6377.e89 res2=00000003 errno=0
+func=rred op1=6228aad4.67d2f8b4 result=bcc95004.9598c2f3.30e res2=00000001 errno=0
+func=rred op1=62362faa.43d52299 result=3c9afb0c.86214902.b01 res2=00000001 errno=0
+func=rred op1=6237d71b.b12906ab result=bcd0501d.764525c7.679 res2=00000003 errno=0
+func=rred op1=6240d8ad.e08a5675 result=bc9f86a6.316afbda.424 res2=00000003 errno=0
+func=rred op1=624b86a6.a71feebd result=3cc16e5b.093e03fc.a05 res2=00000001 errno=0
+func=rred op1=6253842c.122fbc87 result=3c966f72.dad7962b.1de res2=00000001 errno=0
+func=rred op1=625f05dd.8f6f46d8 result=bcca72eb.006b2fa9.157 res2=00000001 errno=0
+func=rred op1=62622e6c.f95d097e result=bca44eec.c3ff30c4.b35 res2=00000003 errno=0
+func=rred op1=6264d9eb.2b026f90 result=3cc04b74.9e6b9746.bbc res2=00000001 errno=0
+func=rred op1=627b45a3.760b8e3d result=bcbe7663.25fec927.0cf res2=00000001 errno=0
+func=rred op1=627c9b62.8ede4146 result=3ca88ff8.f1affb91.888 res2=00000003 errno=0
+func=rred op1=628764e7.c41da562 result=bca00de0.964e65f7.de1 res2=00000001 errno=0
+func=rred op1=6288baa6.dcf0586b result=3cd35d73.bca196b8.ecd res2=00000001 errno=0
+func=rred op1=6294c9aa.5ebd5770 result=bcc85264.e992ca42.aad res2=00000001 errno=0
+func=rred op1=629a0025.297df354 result=3cb08908.a688c895.997 res2=00000003 errno=0
+func=rred op1=62a61749.116d7e69 result=bcd02caa.9a5cfe9f.4cf res2=00000003 errno=0
+func=rred op1=62a8b286.76cdcc5b result=3c5eca04.0e98a76e.d7b res2=00000001 errno=0
+func=rred op1=62b2327d.2c6e4f86 result=bcaf2571.0c2806b4.457 res2=00000003 errno=0
+func=rred op1=62bf328f.c12d4930 result=3cb17f58.c6fd8dd1.103 res2=00000001 errno=0
+func=rred op1=62c61951.2af6216d result=3cc948b5.0a078f7e.219 res2=00000003 errno=0
+func=rred op1=62cb4bbb.c2a57749 result=bcc75c14.c91e0507.341 res2=00000001 errno=0
+func=rred op1=62d0e5e2.86827a0f result=bcab4c30.8a54f1c6.6a8 res2=00000003 errno=0
+func=rred op1=62d765eb.d0e1f6e4 result=3cca3f05.2a7c54b9.985 res2=00000003 errno=0
+func=rred op1=62e4cc34.7ea82335 result=bca399af.86aec7ea.b49 res2=00000003 errno=0
+func=rred op1=62ec98d8.6ef37581 result=3cb931d9.caa3b7ac.c62 res2=00000001 errno=0
+func=rred op1=62f6bf5d.7abaf7c8 result=bc80d2b5.fd89d0cd.22e res2=00000003 errno=0
+func=rred op1=62faa5af.72e0a0ee result=3cc0722d.6724f0c4.3e0 res2=00000001 errno=0
+func=rred op1=63013929.b195f99d result=3cd9b86f.7a900633.2f3 res2=00000001 errno=0
+func=rred op1=630e38ba.3ff2ca86 result=bcd31319.d6c27964.4b8 res2=00000001 errno=0
+func=rred op1=63110f86.1c0c39d6 result=bc993c10.fc4eb933.b45 res2=00000001 errno=0
+func=rred op1=631e625d.d57c8a4d result=3ccdbcd8.aec00a62.058 res2=00000003 errno=0
+func=rred op1=6323e771.cb6398cf result=bcad70be.7bb12d66.fd1 res2=00000001 errno=0
+func=rred op1=632b8a72.26252b54 result=3cde436e.5eac58e8.6e9 res2=00000003 errno=0
+func=rred op1=633181e7.75ae7f09 result=bce4ea25.be7d8c3a.bb5 res2=00000003 errno=0
+func=rred op1=633ed4bf.2f1ecf80 result=3cd7f46a.1f98aa9b.818 res2=00000003 errno=0
+func=rred op1=6342b4ac.a0890bec result=bce8983d.8df3b1e7.9af res2=00000001 errno=0
+func=rred op1=634da1fa.0444429d result=3ccae170.c2451036.977 res2=00000003 errno=0
+func=rred op1=6355ecca.387c8ebd result=3ca76835.15632cd8.af6 res2=00000003 errno=0
+func=rred op1=6358c4b5.e7d3edb6 result=bc947a6d.cb60e983.2cc res2=00000003 errno=0
+func=rred op1=63621232.5298b4cd result=bcd21a5c.da3fdf65.55b res2=00000003 errno=0
+func=rred op1=636f7739.7d0f269f result=3cc9f782.cecf4a09.14f res2=00000001 errno=0
+func=rred op1=6373ff7e.458aa1c5 result=bcc8809f.29ce285e.53b res2=00000001 errno=0
+func=rred op1=637d89ed.8a1d39a7 result=3ca018c5.79b4fb6c.9ba res2=00000003 errno=0
+func=rred op1=6384f624.3f039841 result=bc8186a1.46afb85a.446 res2=00000001 errno=0
+func=rred op1=6389bb5b.e14ce432 result=3ccb6e66.73d06bb3.d64 res2=00000003 errno=0
+func=rred op1=6390ac3f.9976c78e result=bcb6ab41.f436e08e.755 res2=00000001 errno=0
+func=rred op1=63994008.e49068f4 result=3cabcfe2.a1be08c2.a63 res2=00000003 errno=0
+func=rred op1=63a0e9e9.17d5052d result=3cc93d92.4afa74a8.8dc res2=00000001 errno=0
+func=rred op1=63ad4c44.0bbefc08 result=bcbf6e92.978ebcbb.978 res2=00000001 errno=0
+func=rred op1=63b2f006.ab6c4eb7 result=3cc4dbe9.f94e8691.fca res2=00000001 errno=0
+func=rred op1=63bb4626.7827b27e result=bc8cf57f.ae859fc7.8a7 res2=00000003 errno=0
+func=rred op1=63c3f315.7537f37c result=3cb83132.abed54c9.b4e res2=00000001 errno=0
+func=rred op1=63cc4935.41f35743 result=bcd09ef5.493b8b5c.081 res2=00000001 errno=0
+func=rred op1=63d14c9b.bd8bb8c0 result=bcc355f9.41981256.bd1 res2=00000003 errno=0
+func=rred op1=63d79c9d.f6afd2fd result=3cb0f3d2.c04becd7.d24 res2=00000003 errno=0
+func=rred op1=63e29fd8.9961d61e result=3ca36ce5.a95509cb.df5 res2=00000001 errno=0
+func=rred op1=63e64961.1ad9b59f result=bcca9359.2d397a48.9fb res2=00000003 errno=0
+func=rred op1=63f6f2ff.88c4c44e result=bcb33f0c.d9db1ae1.9ac res2=00000001 errno=0
+func=rred op1=63fbefc4.e612c12d result=3cbd2358.7dff8eb1.cf0 res2=00000003 errno=0
+func=rred op1=6404c96c.11134d36 result=3c46ec67.bcf77522.4bc res2=00000003 errno=0
+func=rred op1=64091c93.00763b66 result=bcd34a83.0db9969c.2be res2=00000001 errno=0
+func=rred op1=6415de35.ccec08c2 result=bcc32820.721e236c.787 res2=00000001 errno=0
+func=rred op1=641f2e22.199cf3d1 result=3c61314d.cdb997d9.b8d res2=00000001 errno=0
+func=rred op1=64243f07.3326ef70 result=3cc3b1aa.e08bf02b.463 res2=00000001 errno=0
+func=rred op1=642fb886.f7895197 result=bcc2cc6e.d32a4597.ef4 res2=00000001 errno=0
+func=rred op1=64348439.a21d1e53 result=3cc40d5c.7f7fcdff.cf6 res2=00000001 errno=0
+func=rred op1=643f7354.889322b4 result=bcc242e4.64bc78d9.218 res2=00000003 errno=0
+func=rred op1=6449d92d.dddd0912 result=3cc52071.5c5b677d.6af res2=00000001 errno=0
+func=rred op1=644a1e60.4cd337f5 result=bcc18b81.26d4bd30.0f2 res2=00000003 errno=0
+func=rred op1=6457514c.f7782b24 result=3cc68f37.d82adecf.8fb res2=00000001 errno=0
+func=rred op1=645ca641.333815e3 result=bcbecaae.da3b1469.b01 res2=00000003 errno=0
+func=rred op1=64660d5c.8445bc2d result=3cc96cc4.cfc9cd73.d93 res2=00000001 errno=0
+func=rred op1=646dea31.a66a84da result=bcb63207.f35e487c.d3a res2=00000003 errno=0
+func=rred op1=64703909.4667b164 result=3ccc4a51.c768bc18.22a res2=00000001 errno=0
+func=rred op1=647959ce.dbbee908 result=bca577a8.29c51bd7.5b8 res2=00000003 errno=0
+func=rred op1=6487119d.76691b1f result=3ca86127.5029ce6d.3c1 res2=00000003 errno=0
+func=rred op1=648ba200.4114b6f1 result=bccb8ff1.fdcf8f72.aa8 res2=00000001 errno=0
+func=rred op1=6493035b.24cf2ec6 result=bcc019be.1f53d4e1.84a res2=00000001 errno=0
+func=rred op1=649d6811.2d58d561 result=3cab4aa6.768e8103.1ca res2=00000001 errno=0
+func=rred op1=64a62e95.00470be7 result=bcd2c8b3.248c785c.701 res2=00000001 errno=0
+func=rred op1=64aa3cd7.51e0f840 result=3cc3033d.45b88777.653 res2=00000003 errno=0
+func=rred op1=64b049a5.84685941 result=3cb08ed2.61abf317.6ee res2=00000001 errno=0
+func=rred op1=64b374df.5fe03662 result=bc93a357.2064a2ff.b28 res2=00000003 errno=0
+func=rred op1=64ca0415.34587472 result=3cbc34ce.fb3ebd6e.f11 res2=00000001 errno=0
+func=rred op1=64cd2f4f.0fd05193 result=bcad7502.b096f47f.8bd res2=00000001 errno=0
+func=rred op1=64d02d44.75a4175a result=bcccd4e8.d5ead8f7.3e7 res2=00000001 errno=0
+func=rred op1=64d6bc7a.4a1c556a result=3cb26323.6b0c6bef.17d res2=00000003 errno=0
+func=rred op1=64e518ac.d4fe45e6 result=bc74033b.55837109.aae res2=00000003 errno=0
+func=rred op1=64e86047.bf3a64ee result=3cd2b330.586279b3.3e8 res2=00000001 errno=0
+func=rred op1=64f5ea93.8f8d4da8 result=3cc1c309.90605066.ca8 res2=00000001 errno=0
+func=rred op1=64ffa503.3f7d68d9 result=bc8e04d9.0045298e.805 res2=00000001 errno=0
+func=rred op1=6504afb9.77b6c205 result=bcc583a4.b068f598.9a9 res2=00000001 errno=0
+func=rred op1=650581a0.3245c9c7 result=3cc082d5.db081956.2fd res2=00000003 errno=0
+func=rred op1=651a2a5e.5b9a156f result=bcc9443f.d0719aca.6a9 res2=00000003 errno=0
+func=rred op1=651a9351.b8e19950 result=3cb98475.75fee848.bf9 res2=00000001 errno=0
+func=rred op1=65225b5a.630c9c31 result=bccbc4a7.3b2208eb.9ff res2=00000003 errno=0
+func=rred op1=6527d5ff.46efef9b result=3caf05af.967a5f87.d43 res2=00000001 errno=0
+func=rred op1=6531312a.d8b78947 result=3c9604e8.81eddcfc.52b res2=00000001 errno=0
+func=rred op1=653bbd81.4336ac3a result=bcad0402.6a0ff395.2c7 res2=00000001 errno=0
+func=rred op1=65448395.0fd3bc71 result=3cc24374.db7aeb63.747 res2=00000003 errno=0
+func=rred op1=654f0feb.7a52df64 result=bc8bfc67.a0885a63.671 res2=00000003 errno=0
+func=rred op1=6552da5f.f445a2dc result=3cc7c4ae.fbf662a2.892 res2=00000001 errno=0
+func=rred op1=655d66b6.5ec4c5cf result=bcc041c7.af107f70.cca res2=00000001 errno=0
+func=rred op1=65674bf0.9bbe278b result=bca4fd4d.b86643ca.8d5 res2=00000001 errno=0
+func=rred op1=6568f525.b74c4120 result=3cc44522.07e55756.1c4 res2=00000003 errno=0
+func=rred op1=65729558.9eacbed4 result=bcd121aa.ec14c243.e7e res2=00000001 errno=0
+func=rred op1=657c0288.98cf9042 result=3cba8c10.3f86817a.84f res2=00000003 errno=0
+func=rred op1=6585c53f.2afc7ffa result=3ca91bb8.de84a891.a2d res2=00000003 errno=0
+func=rred op1=658d893a.099137d3 result=bc770576.101d8e8e.218 res2=00000003 errno=0
+func=rred op1=6592a69a.7412f7d6 result=bcaedd16.628c0c35.2b4 res2=00000003 errno=0
+func=rred op1=6598e3e3.e1e6081e result=3cd0697f.3b93d5cf.76d res2=00000001 errno=0
+func=rred op1=65a435ec.cf87bbe8 result=3ca35a5b.5a7d44ee.1a7 res2=00000001 errno=0
+func=rred op1=65abf9e7.ae1c73c1 result=bcc725d0.c9e90927.e07 res2=00000001 errno=0
+func=rred op1=65b36e43.a1cd59df result=bcb52fe8.b54d69be.1e0 res2=00000003 errno=0
+func=rred op1=65be50e3.374b99dc result=3cbd0789.07bbe765.27b res2=00000003 errno=0
+func=rred op1=65c87bbe.d5af48d9 result=bcc05951.deae1882.976 res2=00000003 errno=0
+func=rred op1=65c94368.0369aae2 result=3cc830f2.311c9629.a11 res2=00000001 errno=0
+func=rred op1=65d1af2f.3596c46b result=3cd0ef0f.ef2d9c50.572 res2=00000003 errno=0
+func=rred op1=65db027c.6fa04056 result=bccbdc0c.e6bcdfc9.a82 res2=00000003 errno=0
+func=rred op1=65e28eb9.6bb20f25 result=bcb10363.187f35b7.1b5 res2=00000003 errno=0
+func=rred op1=65e51577.05a306a2 result=3c82b7c2.0ff079b7.f95 res2=00000001 errno=0
+func=rred op1=65fd1974.ee839276 result=bcbfafcd.ef005c37.377 res2=00000003 errno=0
+func=rred op1=65ffa032.887489f3 result=3c9c13a3.17e8b693.f5f res2=00000003 errno=0
+func=rred op1=66011378.1132c0b8 result=3cc6dccf.bd7a5bc0.993 res2=00000003 errno=0
+func=rred op1=66091775.fa134c8c result=bcbb01dd.6b043dc9.392 res2=00000001 errno=0
+func=rred op1=66131477.8b6ae3ad result=3ccb8ac0.41767a2e.979 res2=00000003 errno=0
+func=rred op1=66171676.7fdb2997 result=bcb1a5fc.630c00ed.3c7 res2=00000001 errno=0
+func=rred op1=6620d099.01565674 result=bca09436.b6278822.7fa res2=00000001 errno=0
+func=rred op1=662b5b54.8427d9c5 result=3ca4db4d.69b96b4d.730 res2=00000001 errno=0
+func=rred op1=6632f308.037cae8b result=3cbd2568.c4cd2f5e.b2d res2=00000001 errno=0
+func=rred op1=663938e5.820181ae result=bcb8de52.113b4c33.bf7 res2=00000003 errno=0
+func=rred op1=664504bf.41abec11 result=bcc4b944.63b16a2b.1f8 res2=00000001 errno=0
+func=rred op1=664f8f7a.c47d6f62 result=3cc0b63f.bc2f8944.d32 res2=00000001 errno=0
+func=rred op1=66583009.e2e9e2eb result=3c510483.04009129.bf8 res2=00000001 errno=0
+func=rred op1=665c6430.233f7888 result=bcb05024.aa1785dd.d8a res2=00000003 errno=0
+func=rred op1=6662663e.51f551e1 result=bcc8bc49.0b334b11.6bf res2=00000003 errno=0
+func=rred op1=666df9d5.73de73f5 result=3cc9446d.23534f9a.b9e res2=00000001 errno=0
+func=rred op1=667116fd.da1a04c9 result=3cb1606c.da578ef0.749 res2=00000001 errno=0
+func=rred op1=667f4915.ebb9c10d result=bcae7fb8.f3aef996.795 res2=00000003 errno=0
+func=rred op1=6684a383.de81f3da result=3cb270b5.0a979803.109 res2=00000001 errno=0
+func=rred op1=668bbc8f.e751d1fc result=bcac5f28.932ee771.416 res2=00000003 errno=0
+func=rred op1=66916acd.f810d80f result=bcc767ee.cee33fba.290 res2=00000001 errno=0
+func=rred op1=669ef545.cdc2edc7 result=3ccba90f.8fe36404.98d res2=00000003 errno=0
+func=rred op1=66a140e5.e9156e6c result=3cb6b1d5.cb97bc4d.807 res2=00000001 errno=0
+func=rred op1=66af1f2d.dcbe576a result=bc96b54b.1e5cac8f.03d res2=00000003 errno=0
+func=rred op1=66b67eba.e833a034 result=bcc1063d.ad63094a.813 res2=00000001 errno=0
+func=rred op1=66b9e158.dda025a2 result=3cd10560.58b1cd3a.205 res2=00000003 errno=0
+func=rred op1=66c3dfd0.68a48750 result=3ca6ae60.78d2cc0b.fd1 res2=00000003 errno=0
+func=rred op1=66cacef4.6278fbcf result=bcc6b390.74fa346e.422 res2=00000003 errno=0
+func=rred op1=66d97f7f.22b16f5d result=bca6bc35.c3e68d12.0a8 res2=00000003 errno=0
+func=rred op1=66ddcfb8.9cf6caf8 result=3cc102c8.5a9e1908.fdd res2=00000001 errno=0
+func=rred op1=66e8d7c4.82cda924 result=3ccc59f8.97077f0e.fc6 res2=00000003 errno=0
+func=rred op1=66ee7773.3cda9131 result=bca6ca0b.0efa4e18.17e res2=00000001 errno=0
+func=rred op1=66f163d6.5b8ff666 result=3cd3d894.69b8728a.7d7 res2=00000001 errno=0
+func=rred op1=66fbfb79.2fc60047 result=bcc1109d.a5b1da0f.0b3 res2=00000003 errno=0
+func=rred op1=670025d9.5505adf1 result=3ce26dae.622b45c9.bda res2=00000003 errno=0
+func=rred op1=670fb570.4364d9a6 result=bcc11e72.f0c59b15.18a res2=00000003 errno=0
+func=rred op1=671118b5.283cb548 result=bca71d0a.d170d43c.684 res2=00000001 errno=0
+func=rred op1=671256b2.2ec6fdbd result=3ca63fb6.2034c3db.91f res2=00000003 errno=0
+func=rred op1=6729a50f.bc5b0fec result=bcc155c8.1d149f2d.4e3 res2=00000003 errno=0
+func=rred op1=672ae30c.c2e55861 result=3ca56261.6ef8b37a.bba res2=00000003 errno=0
+func=rred op1=67355ee2.724be29a result=bccce44d.85cd094b.825 res2=00000001 errno=0
+func=rred op1=673f293a.0cf485b3 result=3ca3a7b8.0c8092b9.0f1 res2=00000003 errno=0
+func=rred op1=67433bcb.cd444bf1 result=bcda00ac.2b9eeec3.f54 res2=00000001 errno=0
+func=rred op1=674d0623.67ecef0a result=3cbf363d.7538fcd7.433 res2=00000001 errno=0
+func=rred op1=6750a628.58fe0e2e result=3ca03265.47905135.b5e res2=00000003 errno=0
+func=rred op1=6752c93e.fe05a4d7 result=bcae07b0.5b515743.1a9 res2=00000001 errno=0
+func=rred op1=6768f93c.857d1545 result=3cb84b97.eb5879d0.90d res2=00000001 errno=0
+func=rred op1=676b1c53.2a84abee result=bcb5ee7d.b7892ea8.3fa res2=00000001 errno=0
+func=rred op1=6775e13d.c1c15d0e result=bc96f061.bfe375ca.26e res2=00000003 errno=0
+func=rred op1=677e3451.ee406425 result=3ca4ec99.af2ee786.586 res2=00000001 errno=0
+func=rred op1=678343b3.0d5fb59e result=3cbaa8b2.1f27c4f8.e21 res2=00000003 errno=0
+func=rred op1=67887ec8.7623047e result=bcc8cc89.ef859d61.848 res2=00000001 errno=0
+func=rred op1=67973003.1bf230c6 result=bcce88a2.5f7e7ad4.0e3 res2=00000003 errno=0
+func=rred op1=679f8317.487137dd result=3c8dc282.fa227975.d9e res2=00000003 errno=0
+func=rred op1=67a539db.14a8f332 result=bc9eff82.02b5aed9.60c res2=00000001 errno=0
+func=rred op1=67aedbb4.9b58ce01 result=3cc6c8c1.ded10f1d.b60 res2=00000003 errno=0
+func=rred op1=67b4e629.be1cbe44 result=3cb6a121.fdbea871.452 res2=00000003 errno=0
+func=rred op1=67bfd6c8.9efd6ccb result=bcb73fa1.82084323.089 res2=00000003 errno=0
+func=rred op1=67c51002.6962d8bb result=3c9c8583.f18f4412.530 res2=00000001 errno=0
+func=rred op1=67cfacef.f3b75254 result=bca0bcc0.09ee0cd0.374 res2=00000003 errno=0
+func=rred op1=67da498c.d8ea084c result=3cc271f1.fb43253d.375 res2=00000001 errno=0
+func=rred op1=67da7365.843022c3 result=bcc3aef1.03d65aa0.be3 res2=00000003 errno=0
+func=rred op1=67e7c1b3.f6c97dbf result=bcb91b20.0ee51338.52e res2=00000001 errno=0
+func=rred op1=67ecfb3e.6650ad50 result=3cb42723.ec983daa.376 res2=00000003 errno=0
+func=rred op1=67f668db.30162b3d result=3c8b531f.155186d0.018 res2=00000001 errno=0
+func=rred op1=67fe5417.2d03ffd2 result=bcaaa4b8.4e87b7ec.6e2 res2=00000003 errno=0
+func=rred op1=68071547.936fd47e result=bcc765ee.1d8ffacb.52c res2=00000003 errno=0
+func=rred op1=680da7aa.c9aa5691 result=3cbafbeb.b1ec9f5e.37d res2=00000001 errno=0
+func=rred op1=6812c973.634c1593 result=bc99f651.87bde908.dab res2=00000001 errno=0
+func=rred op1=681a0842.fce040e7 result=3cc0e859.bba08089.1c1 res2=00000003 errno=0
+func=rred op1=6820f9bf.7ce70abe result=bcc09126.583b9917.526 res2=00000003 errno=0
+func=rred op1=68249927.49b12068 result=3c9cafec.a2e52497.284 res2=00000001 errno=0
+func=rred op1=683d1607.0824a5c7 result=bcb2ca56.5f049fe3.10a res2=00000001 errno=0
+func=rred op1=683ee5ba.ee89b09c result=3cb583f1.7a2bdb71.5e3 res2=00000003 errno=0
+func=rred op1=6847efbd.35b85dad result=bcc66053.f3614475.f5b res2=00000001 errno=0
+func=rred op1=6849bf71.1c1d6882 result=3cc1edf3.e5cf36de.792 res2=00000001 errno=0
+func=rred op1=68520602.607afc5b result=3cc919ef.0e888004.434 res2=00000003 errno=0
+func=rred op1=685fa92b.f15ac9d4 result=bcd0ff57.94d64d99.9e2 res2=00000001 errno=0
+func=rred op1=686a2129.9d85f51e result=bca53b0a.1b1dda70.4ff res2=00000001 errno=0
+func=rred op1=686cb44e.86bc192b result=3c8dd38a.1f1d289b.617 res2=00000003 errno=0
+func=rred op1=687236de.a12f42a9 result=3cc7612a.1c1dadfb.144 res2=00000001 errno=0
+func=rred op1=687f784f.b0a68386 result=bcdd7a15.44570d5b.7c3 res2=00000003 errno=0
+func=rred op1=6884e271.aabf89dd result=bc894514.2e3d188a.7cd res2=00000003 errno=0
+func=rred op1=68877596.93f5adea result=3ccb1b9b.6001530e.807 res2=00000003 errno=0
+func=rred op1=6890f983.3cc14236 result=bcb863ac.a0e57d81.9f8 res2=00000001 errno=0
+func=rred op1=6898cb60.18bdd184 result=3ca78245.138de278.c23 res2=00000003 errno=0
+func=rred op1=68a04e9e.7a5d3069 result=3cc7f2f8.da39affd.30e res2=00000001 errno=0
+func=rred op1=68ad5f33.49202af8 result=bcc2831b.5c0204e3.6ef res2=00000001 errno=0
+func=rred op1=68b29888.128e5d23 result=3cc1a1b3.ceaa69da.91a res2=00000001 errno=0
+func=rred op1=68bb1549.b0eefe3e result=bcab07e3.48ec4e9c.376 res2=00000003 errno=0
+func=rred op1=68c3bd7c.dea6f380 result=3ca3fca6.de2f7655.4d1 res2=00000001 errno=0
+func=rred op1=68cc3a3e.7d07949b result=bcd5e417.c51f8eb6.f5e res2=00000001 errno=0
+func=rred op1=68d76963.47caf8df result=bcb1098f.d9d49371.90d res2=00000003 errno=0
+func=rred op1=68dd9c3b.4dfa6d40 result=3cbdfafa.4d47317f.f3a res2=00000003 errno=0
+func=rred op1=68e8acdc.1650b060 result=3cc8fbd0.95bb53ea.a06 res2=00000001 errno=0
+func=rred op1=68ec58c2.7f74b5bf result=bcb814cc.44916bb8.7b2 res2=00000003 errno=0
+func=rred op1=68f145cd.42d21510 result=3cd17d12.0269878a.a37 res2=00000003 errno=0
+func=rred op1=68fed072.1b49942f result=bcc315a2.8d058e23.27d res2=00000003 errno=0
+func=rred op1=690009f5.74e7a5d8 result=3ce03d47.94869025.4ea res2=00000001 errno=0
+func=rred op1=690d949a.4d5f24f7 result=bcd59537.68cb7ced.d17 res2=00000001 errno=0
+func=rred op1=6910a7e1.5bdcdd74 result=3cf0dd2c.cb780bd7.f90 res2=00000003 errno=0
+func=rred op1=691f6e5e.023ecbcb result=bce1d5d8.1f2296bd.d30 res2=00000001 errno=0
+func=rred op1=692058eb.686241a6 result=3d008d3a.2fff4dfe.a3d res2=00000001 errno=0
+func=rred op1=692fbd53.f5b96799 result=bcf135f2.e8311b0b.28a res2=00000003 errno=0
+func=rred op1=69303170.6ea4f3bf result=3d106540.e242ef11.f93 res2=00000001 errno=0
+func=rred op1=693fe4ce.ef76b580 result=bd00e600.4cb85d31.d36 res2=00000003 errno=0
+func=rred op1=69441c5f.ceb2921d result=bc71a702.80a2b3b4.b70 res2=00000001 errno=0
+func=rred op1=694443da.c86fe004 result=3cb2e236.b6254b1a.01a res2=00000003 errno=0
+func=rred op1=695e16d2.392d3438 result=bcb74bf7.564df807.2f6 res2=00000001 errno=0
+func=rred op1=695e3e4d.32ea821f result=3cb0ad56.6610f4a3.6ac res2=00000001 errno=0
+func=rred op1=696905db.87113c37 result=bcd05e89.58b04eca.182 res2=00000003 errno=0
+func=rred op1=69692d56.80ce8a1e result=3cacf0ec.2bf93c59.a7c res2=00000003 errno=0
+func=rred op1=6971a7a1.f2833d10 result=3cca1e71.c1239a30.6b9 res2=00000001 errno=0
+func=rred op1=697ba214.5cfddf2b result=bcc00fbc.4b4fa8f0.c57 res2=00000001 errno=0
+func=rred op1=69805985.878ceb96 result=3c9693d3.56ad1149.e18 res2=00000003 errno=0
+func=rred op1=6987df3a.15d838a4 result=bcc4797c.eb7855dd.f33 res2=00000001 errno=0
+func=rred op1=69988648.4b536161 result=3cb0eede.8101ccf7.692 res2=00000001 errno=0
+func=rred op1=699c4922.927907e8 result=bcbda910.2b9a2316.f5b res2=00000003 errno=0
+func=rred op1=69a28e79.c5dd5338 result=3cd2b42d.b63d116a.ae3 res2=00000001 errno=0
+func=rred op1=69ae7e16.d0c96f8a result=bc9c54f3.53b44734.508 res2=00000003 errno=0
+func=rred op1=69b76bce.2c2b2d90 result=3caefd2d.037ffef9.9ad res2=00000003 errno=0
+func=rred op1=69bd639c.b1a13bb9 result=bcd099d7.4b0855fe.bfe res2=00000001 errno=0
+func=rred op1=69c2c82f.bab3d8c2 result=bcc5e9c4.eaba2358.8ef res2=00000001 errno=0
+func=rred op1=69caf4f2.7e7a4e8d result=3c7541cd.7e5dbe2a.523 res2=00000001 errno=0
+func=rred op1=69d190da.a120622c result=3cc73de1.c29fff3b.341 res2=00000001 errno=0
+func=rred op1=69d519fe.f36f8329 result=bca9acb9.a3e88f6f.064 res2=00000003 errno=0
+func=rred op1=69e80778.b8f4e8db result=bca45c46.44511fe4.71b res2=00000001 errno=0
+func=rred op1=69ede26c.43ffb43f result=3cb4cf09.e1576f07.61f res2=00000003 errno=0
+func=rred op1=69f97e35.9bb79bb4 result=bc9376bf.0a44819e.913 res2=00000001 errno=0
+func=rred op1=69fc6baf.613d0166 result=3cba1f7d.40eede91.f68 res2=00000003 errno=0
+func=rred op1=6a012351.7623e665 result=3cd60675.d1fbb721.4b0 res2=00000003 errno=0
+func=rred op1=6a0eeb9f.fbc5eb51 result=bce5315e.0b266b82.de6 res2=00000001 errno=0
+func=rred op1=6a131ea8.34c9b4c7 result=bcad321e.8f66c26d.d9d res2=00000003 errno=0
+func=rred op1=6a149565.178c67a0 result=3cc7b0a5.5fa64e5e.245 res2=00000003 errno=0
+func=rred op1=6a259310.76df4ed1 result=bcd8028a.163df832.2cf res2=00000003 errno=0
+func=rred op1=6a2d695a.c08fe897 result=3cb22f2c.2fe5da4e.6ee res2=00000001 errno=0
+func=rred op1=6a31e474.13bee7c2 result=3ca0e799.558732fe.4ca res2=00000003 errno=0
+func=rred op1=6a384401.7aacceaf result=bca605e4.bf01d03e.d5c res2=00000003 errno=0
+func=rred op1=6a45b154.d7bb41bb result=bcd159cb.df939b3e.c7a res2=00000003 errno=0
+func=rred op1=6a4ad6ae.1d9e5ba3 result=3cb95b66.004acc7d.730 res2=00000001 errno=0
+func=rred op1=6a509b1d.c2462148 result=bcab2430.287c6d7f.5ed res2=00000001 errno=0
+func=rred op1=6a598d57.cc259529 result=3c8aac0a.0a47e1f4.ea2 res2=00000003 errno=0
+func=rred op1=6a613fc8.eb028485 result=3cb43d1a.96d02f3c.e9f res2=00000001 errno=0
+func=rred op1=6a68e8ac.a36931ec result=bcc45b24.1e5d521f.871 res2=00000003 errno=0
+func=rred op1=6a756690.5b940cd7 result=3cbae81d.196227ba.247 res2=00000003 errno=0
+func=rred op1=6a7db41f.3cb71d7b result=bc4e0987.8d22e29d.291 res2=00000001 errno=0
+func=rred op1=6a8ba0bb.846e5952 result=3caa33e3.ec13566a.758 res2=00000001 errno=0
+func=rred op1=6a8fc782.f4ffe1a4 result=bcac147c.64e58494.481 res2=00000003 errno=0
+func=rred op1=6a91f725.32c8b4fb result=bcc49737.2d7797e4.c16 res2=00000001 errno=0
+func=rred op1=6a9f1026.ad39b12e result=3ce5e058.d59164a3.914 res2=00000001 errno=0
+func=rred op1=6aa5c23e.7f772512 result=3ca8534b.73412840.a2f res2=00000001 errno=0
+func=rred op1=6aa7d5a2.37bfe93b result=bcc50f5d.4bac236f.361 res2=00000001 errno=0
+func=rred op1=6ab2d2ff.fcfb8af2 result=bcafd5ad.5689e0e7.ed3 res2=00000003 errno=0
+func=rred op1=6ab8b17d.01f2bf32 result=3cd0245b.6471d03d.4f2 res2=00000001 errno=0
+func=rred op1=6ac44a9f.3e395802 result=3ca0d0e9.8ff86f99.58a res2=00000001 errno=0
+func=rred op1=6acc3c7f.fb79506b result=bcc7e042.00e768ad.f1e res2=00000001 errno=0
+func=rred op1=6ad38ecf.9d9a717a result=bcb76d38.8e8da91b.40e res2=00000003 errno=0
+func=rred op1=6ade6fee.dd560403 result=3cb9395e.57f4a766.050 res2=00000003 errno=0
+func=rred op1=6ae3ecb7.6de9e4be result=bc9a713b.fa54e607.a0c res2=00000001 errno=0
+func=rred op1=6aee1207.0d0690bf result=3ca46935.22c66c2e.e0f res2=00000003 errno=0
+func=rred op1=6af41bab.56119e60 result=3cbb0584.215ba5b0.c92 res2=00000001 errno=0
+func=rred op1=6afde313.24ded71d result=bcb3d4ec.fbbfac85.b89 res2=00000003 errno=0
+func=rred op1=6b03d53d.79d607ed result=bcd0abd7.8636bfaf.0e9 res2=00000001 errno=0
+func=rred op1=6b0dfa8d.18f2b3ee result=3c628904.e0d7f525.0be res2=00000001 errno=0
+func=rred op1=6b18f3a2.436e4c56 result=bcb9dcf3.d34e265e.786 res2=00000001 errno=0
+func=rred op1=6b190b1c.37822927 result=3ccb4fa8.34df0585.5d5 res2=00000003 errno=0
+func=rred op1=6b2180bb.f73b8dc3 result=3cbc2e14.6f692503.19e res2=00000003 errno=0
+func=rred op1=6b2b7717.ae308022 result=bcb8b463.8540a70c.27b res2=00000003 errno=0
+func=rred op1=6b303f01.41da73dd result=3cbd56a4.bd76a455.6aa res2=00000001 errno=0
+func=rred op1=6b3cb8d2.63919a08 result=bcb66342.e925a867.863 res2=00000003 errno=0
+func=rred op1=6b4d59af.be4226fb result=bcb1c101.b0efab1e.433 res2=00000003 errno=0
+func=rred op1=6b4e9b6a.73a340e1 result=3cc22503.48e3d021.a79 res2=00000001 errno=0
+func=rred op1=6b562b7b.255dc079 result=bcaa3d80.f1735baa.007 res2=00000003 errno=0
+func=rred op1=6b56cc58.800e4d6c result=3cc47623.e4fecec6.490 res2=00000001 errno=0
+func=rred op1=6b629460.d8eb8d38 result=bc8ed1f0.426d9a13.d1f res2=00000003 errno=0
+func=rred op1=6b6a6372.cc8080ad result=3ccdbaa6.556ac958.cf0 res2=00000001 errno=0
+func=rred op1=6b784776.f8ef2093 result=3cc09be5.dcb11b83.cec res2=00000003 errno=0
+func=rred op1=6b7bde91.456153d4 result=bca71d74.31d2338e.dd8 res2=00000001 errno=0
+func=rred op1=6b873979.0f267086 result=bcb34336.2984804c.634 res2=00000003 errno=0
+func=rred op1=6b8cec8f.2f2a03e1 result=3ccf4aac.b53b5d66.607 res2=00000001 errno=0
+func=rred op1=6b9041d4.bdce1b91 result=bcbaf7b2.3a1fe6d1.57b res2=00000001 errno=0
+func=rred op1=6b9f3f1b.4a477588 result=3cde541d.3327f095.c1e res2=00000001 errno=0
+func=rred op1=6ba0e41b.d6787c5e result=bceca5e7.b6a3ebb3.8cd res2=00000003 errno=0
+func=rred op1=6bafe162.62f1d655 result=3cd0d844.1617fd2d.161 res2=00000003 errno=0
+func=rred op1=6bb8119b.905ff8f3 result=3caae357.c8404e23.519 res2=00000001 errno=0
+func=rred op1=6bba6427.ab7d6a9a result=bc7f74c3.d16a5f84.030 res2=00000001 errno=0
+func=rred op1=6bc1d72c.0bf9989b result=bccfcd96.60f8ed0f.f21 res2=00000001 errno=0
+func=rred op1=6bce4c0b.14c6594b result=3cdd5877.149c9d99.a1d res2=00000003 errno=0
+func=rred op1=6bd4f463.ce2cc8c7 result=bcc25bea.7cd8c5fe.494 res2=00000003 errno=0
+func=rred op1=6bdfd3eb.88ce0c6d result=3cb4fd73.10fc5c3a.910 res2=00000001 errno=0
+func=rred op1=6be1133b.d1f5bf0a result=bcc45336.b9ef6bf6.897 res2=00000001 errno=0
+func=rred op1=6be682ff.af4660dd result=3cb10eda.96cf104a.10a res2=00000003 errno=0
+func=rred op1=6bf1da89.c2828b15 result=3ca26353.44e8f0d2.1fd res2=00000003 errno=0
+func=rred op1=6bff0c9d.98414062 result=bc9a22e1.1902dd63.c65 res2=00000003 errno=0
+func=rred op1=6c042ec4.b8e475f9 result=3cc5a7af.68094c7e.98a res2=00000001 errno=0
+func=rred op1=6c0cb862.a1df557e result=bcc2febe.0bd58b6e.7a4 res2=00000003 errno=0
+func=rred op1=6c10b06c.475195a3 result=3ca7b535.fd5072f2.5c7 res2=00000001 errno=0
+func=rred op1=6c1de280.1d104af0 result=bcc98776.521642c7.6be res2=00000001 errno=0
+func=rred op1=6c201b5d.89b91aea result=bc736d58.dd93538b.4ec res2=00000003 errno=0
+func=rred op1=6c21457b.04ea105c result=3cc850a0.c43d0d8e.b6f res2=00000001 errno=0
+func=rred op1=6c38290c.4e95a85f result=bc8d2405.4c5cfd50.f62 res2=00000001 errno=0
+func=rred op1=6c38be1b.0c2e2318 result=3cc719cb.3663d856.020 res2=00000003 errno=0
+func=rred op1=6c43d7ad.8d5b2448 result=bccbf521.6dc8ad38.d5b res2=00000001 errno=0
+func=rred op1=6c4c7a6b.0fd02c76 result=3cc4ac20.1ab16de4.983 res2=00000003 errno=0
+func=rred op1=6c51f985.8b8a1f99 result=bcce62cc.897b17aa.3f9 res2=00000001 errno=0
+func=rred op1=6c5e5893.11a13125 result=3cbfa193.c6993203.890 res2=00000003 errno=0
+func=rred op1=6c651148.ed0fe3fc result=bcd2d5e6.ee492b7f.3e9 res2=00000001 errno=0
+func=rred op1=6c6b40cf.b01b6cc2 result=3cb10f91.206ab35b.0df res2=00000003 errno=0
+func=rred op1=6c75ae16.9cea43d6 result=bc82ee3d.e9450182.066 res2=00000003 errno=0
+func=rred op1=6c78c5d9.fe700839 result=3cd68259.4719b049.f1d res2=00000001 errno=0
+func=rred op1=6c82e4ba.1351af60 result=bcc49c3c.bc27a3a3.6f2 res2=00000003 errno=0
+func=rred op1=6c887773.2682d84c result=3cbfc15a.83acc685.db1 res2=00000001 errno=0
+func=rred op1=6c944968.581df99b result=bcc6fa04.795043d3.aff res2=00000001 errno=0
+func=rred op1=6c9712c4.e1b68e11 result=3cbb05cb.095b8625.598 res2=00000003 errno=0
+func=rred op1=6caa6745.21beafae result=bcce135b.b0ca2464.725 res2=00000003 errno=0
+func=rred op1=6cabcbf3.668af9e9 result=3ca9a639.34cf8a07.a97 res2=00000001 errno=0
+func=rred op1=6cb3517f.5a800dea result=3c8adfed.2e2a2216.8c7 res2=00000001 errno=0
+func=rred op1=6cbe288a.a8f52fd5 result=bcaf2480.86ff7a7e.69a res2=00000001 errno=0
+func=rred op1=6cc47fca.fbb528e0 result=bcc1403f.16625f60.9d9 res2=00000001 errno=0
+func=rred op1=6cccfa3f.07c014df result=3ca427f1.e29f9990.e95 res2=00000003 errno=0
+func=rred op1=6cd2ba59.89e5806f result=3ccb5438.07b22c29.124 res2=00000001 errno=0
+func=rred op1=6cdd9164.d85aa25a result=bcb51087.95afadb5.f4f res2=00000001 errno=0
+func=rred op1=6ce7da4c.48d2caa7 result=3cd2b418.7c80fc78.c37 res2=00000003 errno=0
+func=rred op1=6ce87172.196d5822 result=bc9e8243.fa6a72aa.bac res2=00000001 errno=0
+func=rred op1=6cf5e178.b9f6b306 result=3cb33f5c.2f8f856b.ddc res2=00000001 errno=0
+func=rred op1=6cfb016b.78e3fd3e result=bcc8e0d0.14fcfc0b.4c4 res2=00000003 errno=0
+func=rred op1=6d072975.69b20594 result=3c8ff1d1.92d260b4.032 res2=00000003 errno=0
+func=rred op1=6d09b96e.c928aab0 result=bcd040b0.89cbcc5a.fd8 res2=00000001 errno=0
+func=rred op1=6d168577.11d45c4d result=3cc53e79.48bcab77.1df res2=00000001 errno=0
+func=rred op1=6d17cd73.c18faedb result=bcba8409.c8102694.3a6 res2=00000003 errno=0
+func=rred op1=6d215f18.0f45842f result=3ca7f55d.2e1dc887.026 res2=00000001 errno=0
+func=rred op1=6d2d97d1.1bfc3040 result=bcc884ec.aee30088.fa3 res2=00000001 errno=0
+func=rred op1=6d33f247.908cf03e result=3cd83d24.ee806487.fe4 res2=00000003 errno=0
+func=rred op1=6d3a60a3.42d71aea result=bcc08878.4a2e685b.f96 res2=00000001 errno=0
+func=rred op1=6d48c50c.5644903f result=bc71f1f0.18a7003e.f92 res2=00000001 errno=0
+func=rred op1=6d4e8f69.b0b111a4 result=3cadb393.8fbd80ac.240 res2=00000001 errno=0
+func=rred op1=6d551212.32c50a37 result=3cc765cd.ad589085.0a9 res2=00000001 errno=0
+func=rred op1=6d5c7806.79c41647 result=bcc9a40b.b06d708c.e9c res2=00000003 errno=0
+func=rred op1=6d612131.ea184bd6 result=bcb35645.ce088065.d05 res2=00000003 errno=0
+func=rred op1=6d66eb8f.4484cd3b result=3cc646ae.abce2081.1b0 res2=00000003 errno=0
+func=rred op1=6d703473.61386a54 result=3ca4ba9b.836a008c.a77 res2=00000001 errno=0
+func=rred op1=6d79b1ca.df2471c1 result=bccd0168.b50cc098.b87 res2=00000001 errno=0
+func=rred op1=6d80aad2.a5a85b15 result=bcbc4f3d.da5c0085.4ce res2=00000003 errno=0
+func=rred op1=6d884ead.11d49f7e result=3cbf17e9.451f00d2.fb3 res2=00000003 errno=0
+func=rred op1=6d944190.398684e9 result=3cc9e942.644480af.d15 res2=00000001 errno=0
+func=rred op1=6d9cd229.2e92aad4 result=bcb98692.6f990037.9e9 res2=00000001 errno=0
+func=rred op1=6da27631.6f976fff result=bc932fdb.b0bbfeab.dc6 res2=00000003 errno=0
+func=rred op1=6da6834e.47e58a94 result=3cafdd49.2e7601c3.60b res2=00000001 errno=0
+func=rred op1=6db9aabb.bb3c1ab4 result=bcc18f40.23fb7fc6.c66 res2=00000003 errno=0
+func=rred op1=6dbdb7d8.938a3549 result=3c995ada.fb74062f.08b res2=00000003 errno=0
+func=rred op1=6dc0e27a.b5ec27ef result=3cc7e5f6.e2d88152.888 res2=00000003 errno=0
+func=rred op1=6dc81705.0190d2a4 result=bc8a09b8.cc07ee51.601 res2=00000001 errno=0
+func=rred op1=6dd1ac56.12c1cbf7 result=3cbc9c12.14f503f9.34b res2=00000003 errno=0
+func=rred op1=6dde81b3.f05fd951 result=bcc4d077.3d7c7d90.f26 res2=00000001 errno=0
+func=rred op1=6de21143.c12c9dfb result=bca3874a.9905f2bd.081 res2=00000003 errno=0
+func=rred op1=6de7b217.532600a0 result=3ccafb76.88348514.1eb res2=00000003 errno=0
+func=rred op1=6df243ba.986206fd result=bcd5a0c5.03dcbd03.7d6 res2=00000003 errno=0
+func=rred op1=6dfdea4f.6abf9e4b result=3cc137d1.3bb18bb5.9aa res2=00000001 errno=0
+func=rred op1=6e022a7f.2cc7527c result=bcda8297.aa1e39b2.bf6 res2=00000001 errno=0
+func=rred op1=6e0e038a.d65a52cc result=3c7e37b7.8592d857.d3b res2=00000003 errno=0
+func=rred op1=6e150786.ab915e0f result=bcb8263d.53aec0cb.e2e res2=00000003 errno=0
+func=rred op1=6e1af40c.805ade37 result=3cd4f1e7.3348d4e1.260 res2=00000001 errno=0
+func=rred op1=6e2682a8.20c3be19 result=3c96a9c9.a42e2241.dec res2=00000001 errno=0
+func=rred op1=6e2c8869.6127f2c2 result=bcc7347f.97822a09.244 res2=00000001 errno=0
+func=rred op1=6e374038.db5cee1e result=3cd052f4.78a006d2.4b3 res2=00000001 errno=0
+func=rred op1=6e3d45fa.1bc122c7 result=bcc36d88.a6cfcefe.29c res2=00000001 errno=0
+func=rred op1=6e4320ff.23450bc2 result=3cd2366f.f0f93457.c87 res2=00000001 errno=0
+func=rred op1=6e49e451.1e427070 result=bcbb862c.7b888cdb.643 res2=00000003 errno=0
+func=rred op1=6e54730b.44b7cceb result=bca8d4a1.717e415e.f49 res2=00000003 errno=0
+func=rred op1=6e5bf3ed.fa4e619e result=3c858c58.50525be3.7c8 res2=00000003 errno=0
+func=rred op1=6e657ad9.b2bdc582 result=3cc074a1.47ce91ea.21a res2=00000003 errno=0
+func=rred op1=6e6aec1f.8c486907 result=bcca2d66.f683671d.2c6 res2=00000001 errno=0
+func=rred op1=6e78b763.d6861390 result=3cc3262c.51d8dd66.913 res2=00000001 errno=0
+func=rred op1=6e7f3078.1e16afac result=bcb0c000.535f5ee9.a5e res2=00000003 errno=0
diff --git a/test/testcases/directed/rred5.tst b/test/testcases/directed/rred5.tst
new file mode 100644
index 0000000..d123472
--- /dev/null
+++ b/test/testcases/directed/rred5.tst
@@ -0,0 +1,563 @@
+; rred5.tst
+;
+; Copyright (c) 1999-2018, Arm Limited.
+; SPDX-License-Identifier: MIT
+
+func=rred op1=6e8a55a8.e86a3a97 result=3cc88942.65ed745f.705 res2=00000001 errno=0
+func=rred op1=6e8d9233.0c3288a5 result=bc97e750.acd8c3df.9e9 res2=00000003 errno=0
+func=rred op1=6e95c615.04acdcba result=3c93315f.f3cbf3e7.5a8 res2=00000003 errno=0
+func=rred op1=6e97645a.169103c1 result=bcc92000.7d0f0e5e.78d res2=00000001 errno=0
+func=rred op1=6ea2af28.89dc1a48 result=bcbcb3a8.a9cbc0d9.753 res2=00000001 errno=0
+func=rred op1=6ea8dd01.7f7d9f2c result=3cc7f284.4ecbda60.67d res2=00000003 errno=0
+func=rred op1=6eb7518b.42153df3 result=3cccbedc.4bbed75a.3e7 res2=00000001 errno=0
+func=rred op1=6ebf1da9.499ae9de result=bca30491.6bff99e4.355 res2=00000001 errno=0
+func=rred op1=6ec8e668.e9bb8213 result=bcd0ba66.8265d3a9.414 res2=00000003 errno=0
+func=rred op1=6eca71df.2723e34c result=3ca35e2e.7b984dea.7fa res2=00000001 errno=0
+func=rred op1=6ed81bfa.15e86003 result=3cc808eb.92b20761.fa6 res2=00000001 errno=0
+func=rred op1=6edcc7c4.385f6695 result=bca2aaf4.5c66e5dd.eb0 res2=00000003 errno=0
+func=rred op1=6ee3d567.5d5aea79 result=3cbd0d45.b96474df.bf8 res2=00000003 errno=0
+func=rred op1=6ee62b4c.6e966dc2 result=bcbc5a0b.9a330cd3.2ad res2=00000001 errno=0
+func=rred op1=6ef1b21e.01142fb4 result=bca1f7ba.3d357dd1.566 res2=00000003 errno=0
+func=rred op1=6ef84e95.cadd2887 result=3ca4c4a2.b9fb1e03.a8f res2=00000001 errno=0
+func=rred op1=6f0611fe.941c0980 result=3cd11f37.33f19e30.54e res2=00000003 errno=0
+func=rred op1=6f0a8b2d.019e478e result=bcbaf397.5bd03cba.019 res2=00000001 errno=0
+func=rred op1=6f161ea5.81593ba1 result=bcc675a8.cc82dd45.abf res2=00000003 errno=0
+func=rred op1=6f1cbb1d.4b223474 result=3cc046b4.2aadbe8f.536 res2=00000003 errno=0
+func=rred op1=6f22ca16.25d62627 result=3cad2b5c.304bfe9a.a0c res2=00000001 errno=0
+func=rred op1=6f27369d.a61b3214 result=bc8b1061.287bf420.2ff res2=00000003 errno=0
+func=rred op1=6f3007d6.5352a4f7 result=bcc3a8c0.4fbd3d13.596 res2=00000003 errno=0
+func=rred op1=6f3e6564.f8e3bf31 result=3cb9c950.0b3c8016.9ac res2=00000001 errno=0
+func=rred op1=6f4168f6.3c94658f result=bca44c48.de5cf718.23f res2=00000001 errno=0
+func=rred op1=6f4897bd.8f5cf2ac result=3ccb7a56.1dc43f58.9dc res2=00000003 errno=0
+func=rred op1=6f50b866.47f38543 result=bcd63249.6b88dbf6.5de res2=00000003 errno=0
+func=rred op1=6f5db4d5.0442dee5 result=3cc15431.ae95c3cc.8bc res2=00000001 errno=0
+func=rred op1=6f6110ae.4243f569 result=bcdb455b.a32019bc.66d res2=00000001 errno=0
+func=rred op1=6f6d5c8d.09f26ebf result=3c6a7d3d.5212ce1b.744 res2=00000003 errno=0
+func=rred op1=6f71951a.39bc9da2 result=bca9688d.535ac73e.78b res2=00000003 errno=0
+func=rred op1=6f7d88b1.071aa6d2 result=3cd1892c.2939e968.c2b res2=00000001 errno=0
+func=rred op1=6f8491ff.ed141fee result=3cb003ee.53efbd62.aad res2=00000001 errno=0
+func=rred op1=6f8a5fa7.569aec73 result=bcc30e69.fe84156e.da8 res2=00000001 errno=0
+func=rred op1=6f93138d.13685ec8 result=bca2c93d.fed613b7.9ba res2=00000003 errno=0
+func=rred op1=6f9edaff.e39e2fe5 result=3cc805e5.7de79c14.004 res2=00000003 errno=0
+func=rred op1=6fa3d2c6.803e3f5b result=3cb6a33d.a87470e9.87f res2=00000001 errno=0
+func=rred op1=6fac9d53.9d1c8e2c result=bcbc2ddc.fe411d93.696 res2=00000001 errno=0
+func=rred op1=6fb7d870.5842767a result=bcc77b8d.7e8b98a5.828 res2=00000003 errno=0
+func=rred op1=6fb897a9.c518570d result=3cc1f0ee.28beebfb.a10 res2=00000001 errno=0
+func=rred op1=6fc0b11b.70fb52ef result=bcd07016.3efb5140.a82 res2=00000001 errno=0
+func=rred op1=6fcfbefe.ac5f7a98 result=3cc5caed.d25d492d.8d5 res2=00000003 errno=0
+func=rred op1=6fd4a462.9b09d4fe result=3c980d7e.9c39abaf.8e1 res2=00000003 errno=0
+func=rred op1=6fd706d4.3d76e0d7 result=bca98bbc.af8f5197.703 res2=00000001 errno=0
+func=rred op1=6fe17986.34cc0e0a result=bcdaad05.147d82d8.708 res2=00000003 errno=0
+func=rred op1=6feef693.e88ebf7d result=3cb20a1e.f52b40c3.aa9 res2=00000001 errno=0
+func=rred op1=6ff89c42.7095c451 result=3cd0e8d6.903d0f82.aa3 res2=00000003 errno=0
+func=rred op1=6ffafeb4.1302d02a result=bc9e0676.e990434f.167 res2=00000003 errno=0
+func=rred op1=7007d18b.57065294 result=3cb08be0.e1d59adb.c87 res2=00000003 errno=0
+func=rred op1=700e2bdc.ceff4dc0 result=bcc7492b.e5b2ef15.6f7 res2=00000001 errno=0
+func=rred op1=7019681f.b504915f result=3c788a56.d0d79343.d44 res2=00000001 errno=0
+func=rred op1=701c9548.71010ef5 result=bccecac9.a016ffe9.351 res2=00000003 errno=0
+func=rred op1=702373bc.df42fcba result=bcaaf52c.0f7550e6.9be res2=00000003 errno=0
+func=rred op1=702f5c82.8ac62604 result=3cb39d2b.bbf08d44.430 res2=00000001 errno=0
+func=rred op1=7035a2a4.1b24a7a7 result=3cca5a76.bfcde17d.e9f res2=00000003 errno=0
+func=rred op1=703d2d9b.4ee47b17 result=bcc437e1.0b97fcac.f4e res2=00000001 errno=0
+func=rred op1=704190ff.125307de result=bc9d6001.4e130e89.638 res2=00000003 errno=0
+func=rred op1=70478561.e8149c83 result=3ccd6bc1.99e8d3e6.648 res2=00000003 errno=0
+func=rred op1=70509fa0.2bdb0d70 result=3cbfe257.245c56e6.2d2 res2=00000001 errno=0
+func=rred op1=705a597e.9b7c8bcd result=bcb60800.fa8e4ae7.0aa res2=00000001 errno=0
+func=rred op1=706209ae.858f0515 result=bcd2fc96.465e3b2d.109 res2=00000001 errno=0
+func=rred op1=7069e0cf.28408e96 result=3c8412ae.b24a42e6.4d7 res2=00000001 errno=0
+func=rred op1=7075b8e7.1d49cb3a result=bcbaddab.77c9c62c.99d res2=00000001 errno=0
+func=rred op1=707e08b7.333751f2 result=3cc27381.687773cf.e04 res2=00000003 errno=0
+func=rred op1=7087ccdb.22c52ce8 result=bcb5d8ff.cb373573.067 res2=00000003 errno=0
+func=rred op1=708bf4c3.2dbbf044 result=3cc4f5d7.3ec0bc2c.a9f res2=00000001 errno=0
+func=rred op1=7098d6d5.2582ddbf result=bca79f50.e42427ff.bf7 res2=00000003 errno=0
+func=rred op1=709aeac9.2afe3f6d result=3cc9fa82.eb534ce6.3d5 res2=00000001 errno=0
+func=rred op1=70a2e39e.5cd19285 result=bc7c6511.8ecf28cb.8fd res2=00000003 errno=0
+func=rred op1=70afd405.f0f1d9d0 result=3cb24c5d.995d5059.947 res2=00000003 errno=0
+func=rred op1=70b5dd39.c12a3822 result=bcb965a1.fd111a8c.786 res2=00000001 errno=0
+func=rred op1=70bcda6a.8c993433 result=3ccd38dd.7ef8eb13.17b res2=00000003 errno=0
+func=rred op1=70cad89f.d90e08f9 result=3ca66632.6b530c4d.610 res2=00000003 errno=0
+func=rred op1=70cdd23b.3d66ae96 result=bcc03f73.3062725f.ae3 res2=00000001 errno=0
+func=rred op1=70d6de1f.1aefcdbf result=3c906753.47d6efcf.324 res2=00000003 errno=0
+func=rred op1=70d9d7ba.7f48735c result=bcd4d28a.96b9c676.135 res2=00000003 errno=0
+func=rred op1=70e4e0de.bbe0b022 result=bca43167.eae3b0e3.f6b res2=00000003 errno=0
+func=rred op1=70e8db5f.79feeb5c result=3cba8007.3d48c841.2d9 res2=00000001 errno=0
+func=rred op1=70f06830.7b1db0e8 result=3cd8ec5f.68af8269.dfd res2=00000001 errno=0
+func=rred op1=70ff514e.19d10833 result=bcbe4a1b.e0558955.f20 res2=00000001 errno=0
+func=rred op1=7100a747.3c7012e8 result=3c993a7d.49945d74.dba res2=00000003 errno=0
+func=rred op1=710b17b6.9a606af9 result=bcabc591.30fd330d.7f9 res2=00000001 errno=0
+func=rred op1=7112c412.fc286185 result=bcc10a18.41b12535.5b3 res2=00000003 errno=0
+func=rred op1=7118faea.daa81c5c result=3cb2ebdd.f72f4617.a4b res2=00000001 errno=0
+func=rred op1=7124d119.0b8c17a2 result=3cbf891c.9bf974d2.128 res2=00000003 errno=0
+func=rred op1=712f4188.697c6fb3 result=bcc89e41.87caa75e.e41 res2=00000003 errno=0
+func=rred op1=7132bc30.23fe1545 result=3ccc61cc.f2c6e923.771 res2=00000003 errno=0
+func=rred op1=713d2c9f.81ee6d56 result=bcda31e9.5c63ed36.31d res2=00000003 errno=0
+func=rred op1=7140a355.d05aecc8 result=3cf25fe5.1196871c.536 res2=00000003 errno=0
+func=rred op1=714f3d96.fd674993 result=bc8eed82.59f1f82a.c62 res2=00000003 errno=0
+func=rred op1=7150a93f.f27aa5f8 result=3ca17f1c.b317df6a.2a1 res2=00000001 errno=0
+func=rred op1=715f3f8f.b371dca3 result=bce919f7.91326f3f.8f3 res2=00000003 errno=0
+func=rred op1=7166e8f7.0429f697 result=bcb8364f.8684ebca.782 res2=00000003 errno=0
+func=rred op1=7168fddf.ebb7f8f4 result=3cba3eab.0ca3cf1f.3f2 res2=00000003 errno=0
+func=rred op1=7174d38f.ef194f76 result=3cc5dee3.dfddd744.b49 res2=00000001 errno=0
+func=rred op1=717b1347.00c8a015 result=bcc3d688.59bef3ef.ed9 res2=00000003 errno=0
+func=rred op1=7182be67.f0c9fab7 result=3cd3af00.497adb57.6f5 res2=00000001 errno=0
+func=rred op1=718d286e.ff17f4d4 result=bcd1a6a4.c35bf802.a85 res2=00000003 errno=0
+func=rred op1=7196e8d7.78c94d66 result=bc63c408.220c4c3f.1e0 res2=00000003 errno=0
+func=rred op1=7198fdff.7718a225 result=3cb0e0fc.72077d08.312 res2=00000001 errno=0
+func=rred op1=71a1b3e3.b752a4f0 result=3cda1722.fc5fb686.c0e res2=00000003 errno=0
+func=rred op1=71ae32f3.388f4a9b result=bcd1f5b4.e3e42933.a4d res2=00000001 errno=0
+func=rred op1=71b0240d.9b6f4fad result=bcc26c4d.14b072fd.1f8 res2=00000001 errno=0
+func=rred op1=71bdada1.56234b1f result=3cbfe798.20ddd2ea.778 res2=00000003 errno=0
+func=rred op1=71c49106.8943f8e9 result=3cbeab57.9ebd0e26.85a res2=00000001 errno=0
+func=rred op1=71c940a8.684ea1e3 result=bcc446ad.d7e19a23.0a5 res2=00000003 errno=0
+func=rred op1=71d25a8a.1259a44b result=bcc582ee.5a025ee6.fc3 res2=00000003 errno=0
+func=rred op1=71db7724.df38f681 result=3cb741d4.91f8718e.da6 res2=00000001 errno=0
+func=rred op1=71ea5be6.a3c3cc32 result=bcccec71.66c6fb7e.a77 res2=00000003 errno=0
+func=rred op1=71eeea34.0a33754d result=3ca0dd9c.f0de70bf.07c res2=00000001 errno=0
+func=rred op1=71f52f4f.e34c0e00 result=bc773359.896edc00.b18 res2=00000001 errno=0
+func=rred op1=71fd30ac.74b635e7 result=3ccb793b.ce300dbe.9c5 res2=00000003 errno=0
+func=rred op1=7204528c.188d6e4d result=3cc19737.bd29e79f.0d5 res2=00000003 errno=0
+func=rred op1=720fc6f7.d4f21500 result=bc916683.27132500.852 res2=00000003 errno=0
+func=rred op1=72199e60.116071cd result=3cd13a6a.57042c2f.0a9 res2=00000003 errno=0
+func=rred op1=721a7b23.dc1f1180 result=bc9d002f.ebca9300.dde res2=00000001 errno=0
+func=rred op1=72228965.e6e28c40 result=bca44cee.58410080.9b5 res2=00000003 errno=0
+func=rred op1=722c444a.0dc9f38d result=3ce10c03.a3f14e77.092 res2=00000003 errno=0
+func=rred op1=72313670.e8adcb60 result=bcb2d9b8.bfaa12c0.904 res2=00000001 errno=0
+func=rred op1=723d973f.0bfeb46d result=3cf0f4d0.4a67df9b.087 res2=00000003 errno=0
+func=rred op1=72408cf6.69936af0 result=bcc2201d.f35e9be0.8ab res2=00000001 errno=0
+func=rred op1=724f93ae.894dd5bd result=3d00d203.4419b951.077 res2=00000001 errno=0
+func=rred op1=72503839.2a063ab8 result=bcd1c350.8d38e070.87e res2=00000001 errno=0
+func=rred op1=725fe86b.c8db05f5 result=3d10cc36.6db75d9a.074 res2=00000003 errno=0
+func=rred op1=72600dda.8a3fa29c result=bce194e9.da2602b8.868 res2=00000001 errno=0
+func=rred op1=726fbe0d.29146dd9 result=3d20cf1c.d8e88b75.875 res2=00000001 errno=0
+func=rred op1=72702309.da22eeaa result=bcf1ac1d.33af7194.873 res2=00000003 errno=0
+func=rred op1=727ffd9b.18be5203 result=3d30cac3.381ec6ac.473 res2=00000001 errno=0
+func=rred op1=72800342.e24dfc95 result=bd018950.2d614b4a.863 res2=00000003 errno=0
+func=rred op1=728ff303.70ccabfc result=3d40cb7c.d2eb1223.274 res2=00000001 errno=0
+func=rred op1=7290026c.6443fd25 result=bd452c5d.a8aace08.08c res2=00000001 errno=0
+func=rred op1=729ffcc4.9ab45293 result=3d3d34a5.9a7dd173.acf res2=00000003 errno=0
+func=rred op1=72a002d7.a348fcdd result=bd475d87.ae56f771.598 res2=00000003 errno=0
+func=rred op1=72affc59.5baf52db result=3d3472e3.eefe59a9.e9f res2=00000001 errno=0
+func=rred op1=72b0030d.42cb7cb9 result=bd4bbfdb.b9af4a43.fb1 res2=00000003 errno=0
+func=rred op1=72bffc23.bc2cd2ff result=3d077b04.bffb50b3.1f8 res2=00000001 errno=0
+func=rred op1=72c14bbb.0852575c result=3cb48f13.9646044e.194 res2=00000001 errno=0
+func=rred op1=72c15652.b043fd63 result=bc85222f.9946bd94.c23 res2=00000001 errno=0
+func=rred op1=72d9fc30.346d2911 result=3cae8d0f.5fe8a9d1.d16 res2=00000003 errno=0
+func=rred op1=72da06c7.dc5ecf18 result=bcbf202b.62e96318.7a5 res2=00000003 errno=0
+func=rred op1=72e5a941.7258933a result=3ca3fbf7.93454b07.704 res2=00000001 errno=0
+func=rred op1=72ee59b6.9e7364ef result=bcc4d8a1.97c660f1.6db res2=00000003 errno=0
+func=rred op1=72f37a7e.3d55754b result=3cd70e92.88aeadaf.074 res2=00000001 errno=0
+func=rred op1=72fc2af3.69704700 result=bca64867.9f483022.141 res2=00000001 errno=0
+func=rred op1=7308ea1a.6de46d1d result=3ca1af87.874265ec.cc8 res2=00000003 errno=0
+func=rred op1=730f6bcc.64fc20e3 result=bccab449.8118c99d.473 res2=00000001 errno=0
+func=rred op1=73152036.8f143540 result=bcc0b64d.b7762419.8f1 res2=00000003 errno=0
+func=rred op1=731ff4d7.48407edd result=3c9a2d4e.de79376f.09d res2=00000003 errno=0
+func=rred op1=73219ad8.21e62c60 result=bccbda81.871a3c2a.992 res2=00000001 errno=0
+func=rred op1=732c6f78.db1275fd result=3cb83adb.3ee0b3c8.8ef res2=00000001 errno=0
+func=rred op1=73335d87.587d30d0 result=bcdea38e.7b03422e.dba res2=00000003 errno=0
+func=rred op1=733e3228.11a97a6d result=3cc2a8c1.570ea7c0.09f res2=00000003 errno=0
+func=rred op1=7340b980.869aaa28 result=bcea75fb.0d25b928.77e res2=00000003 errno=0
+func=rred op1=734f137f.acf4fca5 result=3ccfbf68.c64b4377.8ed res2=00000003 errno=0
+func=rred op1=735048d4.b8f4e90c result=bcf9c3b7.d02b77a7.674 res2=00000001 errno=0
+func=rred op1=735f842b.7a9abdc1 result=3cdcf65b.d2623d73.4c5 res2=00000003 errno=0
+func=rred op1=7360107e.d222087e result=bd096a96.31ae56e6.def res2=00000001 errno=0
+func=rred op1=736fbc81.616d9e4f result=3ceb91d5.586dba71.2b1 res2=00000003 errno=0
+func=rred op1=73702ca9.c58b78c5 result=bd199727.00ece747.231 res2=00000003 errno=0
+func=rred op1=737fd8ac.54d70e96 result=3cfadf92.1b7378f0.1a7 res2=00000003 errno=0
+func=rred op1=73820386.3b3edc90 result=3c9a65c3.936ff1e8.a5b res2=00000001 errno=0
+func=rred op1=73821fb1.2ea84cd7 result=bcaf5ded.74d8674f.d55 res2=00000003 errno=0
+func=rred op1=739b0549.58de4ad8 result=3cb3cc52.ae93f56e.7c4 res2=00000003 errno=0
+func=rred op1=739b2174.4c47bb1f result=bcb8c47c.8ffc6ad5.abe res2=00000003 errno=0
+func=rred op1=73a68467.ca0e93b4 result=3cc07f9a.3c25f731.679 res2=00000001 errno=0
+func=rred op1=73afa255.db177243 result=bcc577c4.1d8e6c98.973 res2=00000003 errno=0
+func=rred op1=73b443f7.02a6b822 result=3ccdb27c.05ddf025.ba6 res2=00000001 errno=0
+func=rred op1=73bd61e5.13af96b1 result=bcd71e20.56c56bb7.219 res2=00000001 errno=0
+func=rred op1=73c0e34d.d78aeec7 result=3cd8bf67.5a38f2ca.1b5 res2=00000003 errno=0
+func=rred op1=73ce821d.7763847a result=bce64af2.3a29ec27.dc6 res2=00000003 errno=0
+func=rred op1=73dde3eb.cbd4d572 result=bc9b086a.4bdef35a.b7e res2=00000001 errno=0
+func=rred op1=73df0424.2f88c33b result=3c99c31c.db00f076.938 res2=00000003 errno=0
+func=rred op1=73e0122e.499e5882 result=3cb3a3a9.00783511.f7b res2=00000001 errno=0
+func=rred op1=73ef533d.05501abf result=bcf510b7.aa2268d6.bce res2=00000003 errno=0
+func=rred op1=73f5dad4.a705a931 result=bcc75609.a62b9436.57d res2=00000003 errno=0
+func=rred op1=73f6fb0d.0ab996fa result=3c987dcf.6a22ed92.6f3 res2=00000003 errno=0
+func=rred op1=7403869d.aa2bf7be result=3cc6b362.edbc92c4.45a res2=00000001 errno=0
+func=rred op1=740a6f7c.6b473636 result=bcb4e8f6.715637f6.1c1 res2=00000003 errno=0
+func=rred op1=741540d5.5a72c75c result=3cccd2d6.c8454e28.e17 res2=00000003 errno=0
+func=rred op1=7418b544.bb006698 result=bca1541d.78898259.c8f res2=00000001 errno=0
+func=rred op1=7427d828.e2dcfec9 result=3cafa781.5bbc58cb.157 res2=00000001 errno=0
+func=rred op1=74299260.9323ce67 result=bcc93dfd.cf78988c.8e5 res2=00000003 errno=0
+func=rred op1=743287f3.8c404cf2 result=bcb9fe2c.34ce4386.ad6 res2=00000003 errno=0
+func=rred op1=743e057a.119d186f result=3cb6fd72.9f77979e.310 res2=00000003 errno=0
+func=rred op1=74459e9c.23a059c5 result=bcce5333.92f0a41d.1fa res2=00000003 errno=0
+func=rred op1=744aeed1.7a3d0b9c result=3ccb5279.fd99f834.a33 res2=00000001 errno=0
+func=rred op1=7456bb62.833eac47 result=3c8544dc.8cbb4adf.5d5 res2=00000003 errno=0
+func=rred op1=7459d20b.1a9eb91a result=bcad5703.cde431fb.ba9 res2=00000001 errno=0
+func=rred op1=74631656.bc0f7633 result=bcd4fefd.f2460899.404 res2=00000001 errno=0
+func=rred op1=746d7716.e1cdef2e result=3ccdfb15.8f316190.8ee res2=00000003 errno=0
+func=rred op1=7471d234.0847046a result=bca2b495.87868c8c.0be res2=00000003 errno=0
+func=rred op1=747ba490.fe365424 result=3cbe9f27.507e9125.634 res2=00000001 errno=0
+func=rred op1=748abb4e.0c6a869f result=bcbc0ee0.4b49d2d2.11d res2=00000001 errno=0
+func=rred op1=748fa47c.87622e7c result=3ca7d523.91f00932.aec res2=00000003 errno=0
+func=rred op1=7498bb58.47d49973 result=bc9b280e.fa3a1fca.d1f res2=00000001 errno=0
+func=rred op1=749da486.c2cc4150 result=3cd24a38.1a7d49b9.077 res2=00000001 errno=0
+func=rred op1=74a0d239.25fc0dd4 result=bcb97e99.4615147e.c06 res2=00000003 errno=0
+func=rred op1=74a7bb5d.6589a2dd result=3cc1dfda.ad7406e6.031 res2=00000001 errno=0
+func=rred op1=74b0523b.b4d69289 result=bc7a975b.4250b4c1.19a res2=00000001 errno=0
+func=rred op1=74b83b5a.d6af1e28 result=3cb62bad.ddcafde6.9d2 res2=00000003 errno=0
+func=rred op1=74c486c9.fe5595fe result=bcbcd184.ae5f2b16.e39 res2=00000001 errno=0
+func=rred op1=74cc6fe9.202e219d result=3cb2d8c2.7580e74e.79f res2=00000001 errno=0
+func=rred op1=74d66112.6a825a13 result=3caf0bae.1a6da16c.ad8 res2=00000003 errno=0
+func=rred op1=74da95a0.b4015d88 result=bcc1bbad.bf79ac23.950 res2=00000001 errno=0
+func=rred op1=74e359a7.0fac764e result=3ca1c000.7945470c.20b res2=00000003 errno=0
+func=rred op1=74ed9d0c.0ed7414d result=bcc86184.900dd953.db6 res2=00000001 errno=0
+func=rred op1=74f9ff0f.3caccdb0 result=bcb1b75b.05ae113b.094 res2=00000003 errno=0
+func=rred op1=74fd067a.9782b175 result=3cbaa000.b5e7ea92.311 res2=00000001 errno=0
+func=rred op1=7506ac5b.262ca1ff result=3c214ae7.2e6ba22e.f46 res2=00000001 errno=0
+func=rred op1=750d51c3.532cf961 result=bcd1b984.6293deaf.4f2 res2=00000003 errno=0
+func=rred op1=75102c97.57016e93 result=3cb1c8a5.ecdc7cdd.383 res2=00000003 errno=0
+func=rred op1=751d2c1e.f557d56b result=bcb1a610.1e7fa598.da5 res2=00000001 errno=0
+func=rred op1=75236c79.3e970849 result=3cb1d9f0.d40ae87f.672 res2=00000001 errno=0
+func=rred op1=7529ec3d.0dc23bb5 result=bcb194c5.375139f6.ab5 res2=00000003 errno=0
+func=rred op1=75350c6a.3261d524 result=3cb1fc86.a267bfc3.c51 res2=00000001 errno=0
+func=rred op1=75384c4c.19f76eda result=bcb1722f.68f462b2.4d7 res2=00000003 errno=0
+func=rred op1=754105f8.e85c1dfe result=bcdeef94.62c23285.214 res2=00000001 errno=0
+func=rred op1=754f929f.4b92bfb6 result=3ccafac9.f39b9fa5.a79 res2=00000003 errno=0
+func=rred op1=75516940.99942cb6 result=bcb0e7d8.2f8105a0.d5d res2=00000003 errno=0
+func=rred op1=755bef75.b2c51748 result=3cb31135.154e79e6.b45 res2=00000001 errno=0
+func=rred op1=75633ad5.65fb00ed result=3ccb8521.2d0efcb7.1f3 res2=00000003 errno=0
+func=rred op1=756f60fb.72f6b85a result=bcad7cf6.936722b5.ee8 res2=00000003 errno=0
+func=rred op1=7578651e.06457288 result=bcc84715.d45ace4e.517 res2=00000001 errno=0
+func=rred op1=757da838.92dde7d1 result=3cb763ee.e0e96272.717 res2=00000001 errno=0
+func=rred op1=75832e6c.6fd3ff16 result=bca4d782.fc31519e.745 res2=00000003 errno=0
+func=rred op1=758a2a49.dc8544e8 result=3cbbb6a8.ac844afe.2e8 res2=00000001 errno=0
+func=rred op1=75909313.a49b455d result=3cd07644.b5c84fb2.e5c res2=00000003 errno=0
+func=rred op1=759cc5a2.a7bdfea1 result=bcbf4344.7a49fa6d.ae7 res2=00000001 errno=0
+func=rred op1=75a021c8.af0b50c5 result=3c9b7c96.c14be57e.e8e res2=00000003 errno=0
+func=rred op1=75a9b8fe.e6f55050 result=bcabf0ba.97bcb07d.743 res2=00000001 errno=0
+func=rred op1=75b36711.ea9bf962 result=3cc4ba7a.06951ede.d17 res2=00000003 errno=0
+func=rred op1=75bcfe48.2285f8ed result=bc4d08f5.9c32bfa2.d3a res2=00000003 errno=0
+func=rred op1=75c34abf.2d37fc3c result=bcc4f48b.f1cd845e.172 res2=00000003 errno=0
+func=rred op1=75c69008.68c8a4d9 result=3cab0872.eadb1a80.5d9 res2=00000001 errno=0
+func=rred op1=75d0139f.50595232 result=bcd17674.9ed5ee4e.68a res2=00000001 errno=0
+func=rred op1=75d9c728.45a74ee3 result=3caa202b.3df98483.46f res2=00000003 errno=0
+func=rred op1=75eb62b8.3416a3e8 result=3ca84f9b.e4365889.19b res2=00000003 errno=0
+func=rred op1=75ee99d8.10f54df2 result=bcaf91d9.4b430871.cea res2=00000001 errno=0
+func=rred op1=75f0e87b.f6e9fbfe result=bcc5dcd3.9eaf1a5b.2dc res2=00000003 errno=0
+func=rred op1=75ff6eb4.b785f7be result=3ce98379.2c97b4f7.cbf res2=00000001 errno=0
+func=rred op1=76048a0a.2710faee result=3cc23bb4.eb28c266.d34 res2=00000001 errno=0
+func=rred op1=7606259a.15804ff3 result=bcb36a0b.5927dc2d.41c res2=00000001 errno=0
+func=rred op1=76111db3.208e2671 result=3cce6382.dd43eeab.602 res2=00000003 errno=0
+func=rred op1=761991f1.1c032470 result=bcbaac48.c0348c15.f6b res2=00000001 errno=0
+func=rred op1=7620354f.948466b5 result=bc82e566.dff19c66.e78 res2=00000003 errno=0
+func=rred op1=7623a1a6.9b073b32 result=3cb5f2ef.083824fc.3cc res2=00000001 errno=0
+func=rred op1=763699cb.db852fd1 result=bcbf65a2.7830f32f.b08 res2=00000003 errno=0
+func=rred op1=763a0622.e208044e result=3cb13995.503bbde2.82e res2=00000003 errno=0
+func=rred op1=7643678d.b804cb43 result=bcc20f7e.1816ad24.b53 res2=00000001 errno=0
+func=rred op1=764d3861.058868dc result=3c9f1b87.810bbebc.3cb res2=00000003 errno=0
+func=rred op1=765b9f41.f3c83695 result=3cc51d06.405d35ba.0a8 res2=00000001 errno=0
+func=rred op1=765ed180.17489b23 result=bca63d09.ff5d596f.b0a res2=00000003 errno=0
+func=rred op1=7665ea48.c4264ea5 result=3cb754a5.a0c8cf0d.2d8 res2=00000001 errno=0
+func=rred op1=76678367.d5e680ec result=bcbe03eb.dfa0491e.bfd res2=00000003 errno=0
+func=rred op1=76730fcc.2c555aad result=bcacec50.3e34d381.42e res2=00000001 errno=0
+func=rred op1=767a5de4.6db774e4 result=3c7179ba.16b759d7.ce5 res2=00000003 errno=0
+func=rred op1=76847d0a.783dd4a9 result=3cc01991.913b9a2c.dcc res2=00000003 errno=0
+func=rred op1=7688f0a6.21cefae8 result=bccd781e.0eea8e50.016 res2=00000001 errno=0
+func=rred op1=7693c66b.524997ab result=3c8a3697.221306c3.b58 res2=00000001 errno=0
+func=rred op1=7699a745.47c337e6 result=bccc6082.6d7f18b2.847 res2=00000003 errno=0
+func=rred op1=76a421ba.e543b62a result=3cd0eb46.4a4c3262.fa7 res2=00000003 errno=0
+func=rred op1=76aa0294.dabd5665 result=bcca314b.2aa82d77.8aa res2=00000003 errno=0
+func=rred op1=76b0a856.8e0fb84e result=3cd202e1.ebb7a800.776 res2=00000003 errno=0
+func=rred op1=76bd7bf9.31f15441 result=bcc4bb41.038ee164.1a3 res2=00000001 errno=0
+func=rred op1=76c5831d.7de39699 result=3cd66150.71657e76.6af res2=00000003 errno=0
+func=rred op1=76cf38ab.5d8b532f result=bcb39e59.6ab8927a.726 res2=00000001 errno=0
+func=rred op1=76d2e812.3c7c9834 result=bca5c2f8.beb9cb1d.167 res2=00000001 errno=0
+func=rred op1=76d97f8b.57ea756d result=3c9a60f6.dd69d125.0c9 res2=00000001 errno=0
+func=rred op1=76e00b82.39ac2953 result=3cb811f7.ce11ce21.118 res2=00000001 errno=0
+func=rred op1=76ec5c1b.5abae44e result=bcc0523a.8f0b5855.d0d res2=00000003 errno=0
+func=rred op1=76f7a216.cb9bbe41 result=bccb33b6.ee683de4.5c1 res2=00000001 errno=0
+func=rred op1=76fe398f.e7099b7a result=3caefef4.fc19d72d.02a res2=00000001 errno=0
+func=rred op1=7703d6cc.82a3f3ca result=bc990df9.02b37e1a.547 res2=00000003 errno=0
+func=rred op1=770f284a.2d30f710 result=3cdbf1d6.6d950906.b1d res2=00000001 errno=0
+func=rred op1=7719082e.34d6c7a2 result=3cb8bb76.bb6cf7a6.6d9 res2=00000001 errno=0
+func=rred op1=771dc232.c3f5edaf result=bcb2ca7a.c2069e93.bf5 res2=00000001 errno=0
+func=rred op1=77213e1b.a98a89de result=bccf2836.1fbd1a66.f61 res2=00000001 errno=0
+func=rred op1=77266f7d.5bbd5db6 result=3ca868f4.74267132.86b res2=00000003 errno=0
+func=rred op1=77352324.ef30a8c0 result=bca9b2fd.91408b02.222 res2=00000003 errno=0
+func=rred op1=7737bbd5.c84a12ac result=3cced5b3.d87693f3.0f4 res2=00000001 errno=0
+func=rred op1=7745c951.2577033b result=3ca71eeb.570c5762.eb4 res2=00000001 errno=0
+func=rred op1=774fb4b7.66c8fd20 result=bcc3463e.2cf06841.999 res2=00000001 errno=0
+func=rred op1=775a6bee.2afcd2f0 result=bcd00fde.7ac856e1.555 res2=00000003 errno=0
+func=rred op1=775b121a.61432d6b result=3ca48ad9.1cd823c3.b47 res2=00000001 errno=0
+func=rred op1=77627ec0.514a93a8 result=bcd67c9d.df1879a1.dde res2=00000001 errno=0
+func=rred op1=776db67e.ff294283 result=3c9ec569.50df790a.8d8 res2=00000001 errno=0
+func=rred op1=77712c8e.0257891c result=bce4e16e.060470f1.bbc res2=00000003 errno=0
+func=rred op1=777f08b1.4e1c4d0f result=3c8449ae.fe7bb821.ad7 res2=00000001 errno=0
+func=rred op1=778e5f98.26a2c7c9 result=3cb1ebea.883f3389.7c6 res2=00000003 errno=0
+func=rred op1=778fb1ca.7595d255 result=bc9f1c4c.24055de2.96d res2=00000001 errno=0
+func=rred op1=779eb424.ba5f8a6c result=3cb6fe56.47de2191.e7c res2=00000001 errno=0
+func=rred op1=779f5d3d.e1d90fb2 result=bc85a53a.4b134b81.d2b res2=00000003 errno=0
+func=rred op1=77a0032b.84a94a7c result=bcbc67a4.daa2f472.5c7 res2=00000001 errno=0
+func=rred op1=77afda9a.46da9e41 result=3d12582e.68f5c6f8.45c res2=00000001 errno=0
+func=rred op1=77b75ba8.1f846a74 result=3cb19507.b5194eb1.731 res2=00000003 errno=0
+func=rred op1=77b7b034.b3412d17 result=bcc0e879.b6b3e3a9.689 res2=00000003 errno=0
+func=rred op1=77c3af69.d216da78 result=bcc39d21.00164d19.a2f res2=00000001 errno=0
+func=rred op1=77cb5c73.00aebd13 result=3c9b09aa.3e3ea3c2.270 res2=00000003 errno=0
+func=rred op1=77d184be.17a34fd7 result=3cca5f8b.8fa5f60a.2ca res2=00000001 errno=0
+func=rred op1=77d58588.f8cda276 result=bc9040ca.57e7f341.7e7 res2=00000003 errno=0
+func=rred op1=77e099ae.8447ebd8 result=3cbf19dc.d438a092.869 res2=00000001 errno=0
+func=rred op1=77ea7163.6d535914 result=bcc7ad53.961049ea.028 res2=00000003 errno=0
+func=rred op1=77f7fb76.33107dc5 result=bccbbd86.2c0a46ba.622 res2=00000001 errno=0
+func=rred op1=77fdd260.3af19862 result=3cadb224.f8a15aa2.105 res2=00000001 errno=0
+func=rred op1=78073607.5f9cc21d result=3cd34333.09307b9d.855 res2=00000003 errno=0
+func=rred op1=7809abf4.99df9d6c result=bc767b7d.b9745f07.644 res2=00000001 errno=0
+func=rred op1=781798be.c9569ff1 result=bcc0f4a6.45b39639.b99 res2=00000001 errno=0
+func=rred op1=781bbf2a.6a689ae7 result=3cbc4a6d.1d0a14b1.9a1 res2=00000003 errno=0
+func=rred op1=782340f7.7367b611 result=bc90dc9e.4b174745.8b3 res2=00000003 errno=0
+func=rred op1=7825542d.43f0b38c result=3cccfe49.0ad5b7a9.d53 res2=00000001 errno=0
+func=rred op1=78356cdb.1e5f2b01 result=bcd20270.2a650aae.124 res2=00000001 errno=0
+func=rred op1=783deb0e.15600fd7 result=3cc8c721.780fe5d8.726 res2=00000003 errno=0
+func=rred op1=784456e9.48e37089 result=bcd41e03.f3c7f396.c3b res2=00000003 errno=0
+func=rred op1=784f00ff.eadbca4f result=3cc1c08a.2e1b8826.231 res2=00000001 errno=0
+func=rred op1=7853cbf0.5e25934d result=bcd8552b.868dc568.268 res2=00000003 errno=0
+func=rred op1=785f8bf8.d599a78b result=3c9d9adc.d196660c.231 res2=00000001 errno=0
+func=rred op1=7862fb7a.fe08c773 result=bc8eb83d.42a4b005.4af res2=00000001 errno=0
+func=rred op1=786f467c.603ab8ed result=3cd39a37.fb34ee86.e54 res2=00000003 errno=0
+func=rred op1=787943b9.e9d1377f result=3ca5eccd.80ed3a0a.d05 res2=00000003 errno=0
+func=rred op1=787faeb7.10491eda result=bcc1004a.59391084.b03 res2=00000003 errno=0
+func=rred op1=78861f9a.73ecff79 result=3c8a42bb.7e6b8820.ab7 res2=00000001 errno=0
+func=rred op1=788c8a97.9a64e6d4 result=bcd5a967.dd8102c6.5ef res2=00000001 errno=0
+func=rred op1=78948d8a.b8fae376 result=bca8278e.6309cdfd.201 res2=00000001 errno=0
+func=rred op1=7897b1aa.2edf1b7c result=3cb93524.f0baab0e.e5c res2=00000003 errno=0
+func=rred op1=78a08f04.4845e1c7 result=3ce121fd.2aef2c26.e8e res2=00000001 errno=0
+func=rred op1=78aed450.15785531 result=bcc21daa.ca475a7d.d81 res2=00000003 errno=0
+func=rred op1=78b0332f.e835389a result=3c70d968.db0dd11c.5b0 res2=00000001 errno=0
+func=rred op1=78ba79f5.44b2aa55 result=bcb719f7.d558f0eb.5a6 res2=00000003 errno=0
+func=rred op1=78c2605d.50980e08 result=bcc7a0c3.1c315f74.3d4 res2=00000001 errno=0
+func=rred op1=78c84cc7.dc4fd4e7 result=3c89461d.4894b9aa.888 res2=00000003 errno=0
+func=rred op1=78d73631.281e6a30 result=3ccbd71d.52f4d3bb.540 res2=00000003 errno=0
+func=rred op1=78d9635e.90813f9e result=bcc58596.00cfa550.b1e res2=00000001 errno=0
+func=rred op1=78e3b4b0.8829d165 result=3ccdf24a.6e568dde.df6 res2=00000003 errno=0
+func=rred op1=78ece4df.3075d869 result=bcc14f3b.ca0c3109.9b2 res2=00000001 errno=0
+func=rred op1=78f600bc.323cd326 result=3cd221e8.e03dde24.c0c res2=00000003 errno=0
+func=rred op1=78fa98d3.8662d6a8 result=bcb5fb68.efce053d.f20 res2=00000001 errno=0
+func=rred op1=79056601.b74c07a1 result=bc948800.5300d086.5be res2=00000001 errno=0
+func=rred op1=790d7f99.ab66a3ee result=3ca76ed1.8c9b39f5.881 res2=00000001 errno=0
+func=rred op1=7916d964.c9cdee44 result=3cc6b51d.3e349f99.bd0 res2=00000001 errno=0
+func=rred op1=791c0c36.98e4bd4b result=bcc01fb4.8ca736c0.8ff res2=00000003 errno=0
+func=rred op1=792212e7.467faccc result=3c773689.ccd34b79.615 res2=00000003 errno=0
+func=rred op1=7928b91c.28186276 result=bcc541b4.a1676ae2.26f res2=00000001 errno=0
+func=rred op1=793b1c5a.e9bf8332 result=3c9168e7.599e789b.090 res2=00000001 errno=0
+func=rred op1=793e6f75.5a8bde07 result=bcc3ce4c.049a362a.90e res2=00000003 errno=0
+func=rred op1=794697a1.181f97ff result=3c9d042c.40081e57.b9b res2=00000003 errno=0
+func=rred op1=7949eabb.88ebf2d4 result=bcd42b26.2bcd8358.766 res2=00000003 errno=0
+func=rred op1=7952abb6.f6e974fb result=3cd93f14.509bbbdb.03a res2=00000003 errno=0
+func=rred op1=795f0845.0af5a636 result=bcd14454.f23319e9.4a3 res2=00000003 errno=0
+func=rred op1=79601cf2.35e49b4a result=3cdb6c31.3bcf8aee.64d res2=00000001 errno=0
+func=rred op1=796d124f.fa5a94b4 result=bcc9d436.3796f785.0ff res2=00000003 errno=0
+func=rred op1=797117ec.be32240b result=3ce09ce9.d7822ee6.5e9 res2=00000001 errno=0
+func=rred op1=797c1755.720d0bf3 result=bcb0d69d.bbf0fdd4.0dd res2=00000003 errno=0
+func=rred op1=79804e07.a1d67b93 result=bc94ed63.561d605d.74a res2=00000003 errno=0
+func=rred op1=7984d2c1.737666c6 result=3cb1fb30.f74bf362.043 res2=00000003 errno=0
+func=rred op1=799632ae.89f1c3c3 result=bcc3744a.26b4a9df.bc6 res2=00000001 errno=0
+func=rred op1=799ab768.5b91aef6 result=3c9e11fd.30f50ccd.277 res2=00000001 errno=0
+func=rred op1=79a7c514.e7840ade result=3cc5bd70.9d6a94fb.a92 res2=00000003 errno=0
+func=rred op1=79ada9bb.cf9f530e result=bcaad1c8.13c03a54.558 res2=00000001 errno=0
+func=rred op1=79bc3092.15988102 result=3c7a01a8.e9a693c6.8f8 res2=00000003 errno=0
+func=rred op1=79bf22e5.89a6251a result=bccba1d5.5b0d6ef2.8a0 res2=00000001 errno=0
+func=rred op1=79cb73fd.389517fc result=3cbfb217.bf8f7609.907 res2=00000003 errno=0
+func=rred op1=79cced26.f29bea08 result=bcb931ad.8525d117.ec9 res2=00000001 errno=0
+func=rred op1=79dbd247.a716cc7f result=3cc17926.6e622441.313 res2=00000001 errno=0
+func=rred op1=79dc8edc.841a3585 result=bcb5f178.67f0fe9f.1aa res2=00000003 errno=0
+func=rred op1=79e4f548.58f18680 result=3cc31940.fcfc8d7d.9a2 res2=00000003 errno=0
+func=rred op1=79e55392.c7733b03 result=bcb2b143.4abc2c26.48b res2=00000001 errno=0
+func=rred op1=79f1b5ed.e91fbdc2 result=bca861b2.20a50e69.49a res2=00000001 errno=0
+func=rred op1=79ffce36.f3ebfe43 result=3c69ff6c.901855d4.5e2 res2=00000001 errno=0
+func=rred op1=7a06f33f.ff5c1f62 result=3caba19f.b2a81923.d56 res2=00000001 errno=0
+func=rred op1=7a0a90e4.ddaf9ca3 result=bcc24945.987bcace.f73 res2=00000003 errno=0
+func=rred op1=7a145496.f43dee92 result=bca521c4.8ea203ae.bde res2=00000003 errno=0
+func=rred op1=7a1991e9.0a7a5032 result=3cd07508.6b284d07.c26 res2=00000001 errno=0
+func=rred op1=7a25a3eb.79cd06fa result=3cb110bd.6b57174c.767 res2=00000001 errno=0
+func=rred op1=7a2e7ee2.6e5ce5db result=bcbfb2a6.d5f30586.1cc res2=00000001 errno=0
+func=rred op1=7a34fc41.37057ac6 result=bc90441c.8d2bb189.1d8 res2=00000003 errno=0
+func=rred op1=7a364b95.bc94932e result=3cd214ff.3429d265.085 res2=00000001 errno=0
+func=rred op1=7a455016.586940e0 result=3cbe1073.b3634236.a59 res2=00000001 errno=0
+func=rred op1=7a4f7a61.d2883829 result=bca8662a.d3c18a4d.ac5 res2=00000001 errno=0
+func=rred op1=7a54d256.a65397b9 result=bccb3b4f.43926642.28f res2=00000001 errno=0
+func=rred op1=7a5fa44c.633a1b36 result=3cab98ae.4c6f215b.100 res2=00000001 errno=0
+func=rred op1=7a6a5046.cd1fcafe result=bc83be2b.37a106dc.ac3 res2=00000001 errno=0
+func=rred op1=7a6a7a31.5dd1ae0b result=3cd27b4f.a33f8546.b4c res2=00000003 errno=0
+func=rred op1=7a77a644.0212a2e2 result=bcc17fff.40a5c1f6.e85 res2=00000001 errno=0
+func=rred op1=7a7cfa49.982cf31a result=3cb920e8.e57b007f.7a8 res2=00000003 errno=0
+func=rred op1=7a88fb45.679936f0 result=bcc3f7c4.a799e2d2.7dd res2=00000003 errno=0
+func=rred op1=7a8ba548.32a65f0c result=3cb4315e.1792bec8.4f7 res2=00000001 errno=0
+func=rred op1=7a99a5c6.1a5c80f7 result=bcc8e74f.75822489.a8e res2=00000003 errno=0
+func=rred op1=7a9afac7.7fe31505 result=3ca4a490.f78476b3.f2b res2=00000001 errno=0
+func=rred op1=7aa366f4.c076333b result=bccdd6da.436a6640.d3f res2=00000003 errno=0
+func=rred op1=7aa41175.73397d42 result=3c5cccb7.fc6dfae8.d1e res2=00000001 errno=0
+func=rred op1=7ab730de.202ca420 result=bcc38491.c7a82ae6.da9 res2=00000001 errno=0
+func=rred op1=7abe1a30.2cd63be3 result=3c759989.fd527c2e.9d7 res2=00000003 errno=0
+func=rred op1=7ac281c1.1cbfe9d3 result=3cc4de2a.677d52a9.c46 res2=00000001 errno=0
+func=rred op1=7acfa9e4.834fcf52 result=bcc29e2c.07c4bb0f.940 res2=00000001 errno=0
+func=rred op1=7ad84df8.a4cb12db result=3cc637c3.07527a6c.ae3 res2=00000003 errno=0
+func=rred op1=7ad9ddac.fb44a64a result=bcc1b7c6.47e14b38.4d7 res2=00000001 errno=0
+func=rred op1=7ae12b59.af33e8be result=3cc71e28.c735ea43.f4c res2=00000003 errno=0
+func=rred op1=7ae6f791.373f11c6 result=bcbfd5f5.9034d713.80a res2=00000001 errno=0
+func=rred op1=7af29e67.9136b300 result=3ccab7bf.c6c3a9a1.0f0 res2=00000003 errno=0
+func=rred op1=7aff8d3e.0ed90625 result=bcb16f99.91fdd99f.17a res2=00000001 errno=0
+func=rred op1=7b04cafc.643ae263 result=bca478d7.25c4b5c9.c65 res2=00000001 errno=0
+func=rred op1=7b0ed3b7.1dd7a104 result=3c90a7c1.ad528a3e.172 res2=00000001 errno=0
+func=rred op1=7b197296.48888f23 result=3cc07b54.33e14ebc.2bd res2=00000001 errno=0
+func=rred op1=7b1a2c1d.3989f444 result=bcc68dcf.5b6f0711.894 res2=00000003 errno=0
+func=rred op1=7b271ec9.5661b8c3 result=3ca8fba2.83fbcf5d.22c res2=00000003 errno=0
+func=rred op1=7b2c7fea.2bb0caa4 result=bcc263de.f01a6482.037 res2=00000001 errno=0
+func=rred op1=7b3093c2.07ff3bb2 result=3cd185d0.4eb67760.0d4 res2=00000003 errno=0
+func=rred op1=7b3da9d0.a4c435d4 result=bcb41ffc.32e23ec5.efb res2=00000001 errno=0
+func=rred op1=7b4689d6.19d8032b result=bc8bc1d4.2c7da43e.c45 res2=00000001 errno=0
+func=rred op1=7b4e3ec3.e14deb6c result=3caa5f0e.4f85ab6c.7d4 res2=00000001 errno=0
+func=rred op1=7b56d44f.b81cddf7 result=3cc73f85.4133f519.367 res2=00000001 errno=0
+func=rred op1=7b5df44a.430910a0 result=bcbb1071.3e01a7d5.a0c res2=00000003 errno=0
+func=rred op1=7b66af12.e8fa7091 result=3cc3c74a.bba44091.5df res2=00000003 errno=0
+func=rred op1=7b6e1987.122b7e06 result=bc662c5d.cf7f8d24.707 res2=00000001 errno=0
+func=rred op1=7b769c74.816939de result=3cb9adab.6109af03.59c res2=00000003 errno=0
+func=rred op1=7b7e06e8.aa9a4753 result=bccb6922.b53fa60a.328 res2=00000003 errno=0
+func=rred op1=7b82cb4c.d176e117 result=bcbc7337.1af9a0a7.e7d res2=00000001 errno=0
+func=rred op1=7b8a5afd.c9ca5bf2 result=3cb84ae5.8411b631.12b res2=00000001 errno=0
+func=rred op1=7b90ec08.2d46500d result=bcbdd5fc.f7f1997a.2ed res2=00000003 errno=0
+func=rred op1=7b9c3a42.6dfaecfc result=3cb58559.ca21c48c.84a res2=00000001 errno=0
+func=rred op1=7bad29e4.c0133581 result=3caff484.ac83c286.d11 res2=00000001 errno=0
+func=rred op1=7baf0929.6443c68b result=bcc31350.12e0b733.ec8 res2=00000003 errno=0
+func=rred op1=7bb61b54.24947a42 result=3ca4de55.c4c3fbf4.98e res2=00000001 errno=0
+func=rred op1=7bb70af6.76acc2c7 result=bcc5d8db.ccd0a8d8.7a9 res2=00000003 errno=0
+func=rred op1=7bc21c3a.adc8f860 result=3ccabcef.3b52c389.aae res2=00000003 errno=0
+func=rred op1=7bca1a6d.9b5ffc24 result=bca77a65.da3b1e54.481 res2=00000001 errno=0
+func=rred op1=7bd81ae0.dffa3b33 result=3ca24245.af4cd994.e9b res2=00000003 errno=0
+func=rred op1=7bdc19fa.56c5bd15 result=bccc0af7.460e54b9.827 res2=00000001 errno=0
+func=rred op1=7be393d2.3487fd1b result=bcc19bcc.63ac56bf.360 res2=00000003 errno=0
+func=rred op1=7beea17c.46d23a3c result=3c9a144b.08bd29ab.16b res2=00000003 errno=0
+func=rred op1=7bf5d759.8a411c27 result=bcb0f553.180bd3e9.826 res2=00000001 errno=0
+func=rred op1=7bfa5e68.35b35a3f result=3cd67f9a.754fce8f.4a4 res2=00000003 errno=0
+func=rred op1=7c06f91d.351dabad result=3cb38f38.468ddf40.510 res2=00000001 errno=0
+func=rred op1=7c0d7fb8.9bf5aab6 result=bcbb6593.6de85d68.3f1 res2=00000001 errno=0
+func=rred op1=7c1789ff.0a8bf370 result=3cd72613.c0f05164.fdf res2=00000001 errno=0
+func=rred op1=7c1e109a.7163f279 result=bc751486.52b33bd2.860 res2=00000001 errno=0
+func=rred op1=7c22dc7c.c18c4084 result=3ca771ba.3e66c230.c5f res2=00000003 errno=0
+func=rred op1=7c29f3f9.fdd28750 result=bcd149a5.3156a0d8.cc7 res2=00000001 errno=0
+func=rred op1=7c34a25c.109dd237 result=bcb0fdfe.b3e0300d.047 res2=00000001 errno=0
+func=rred op1=7c3c4abb.225260c6 result=3cc1954b.aecd11a4.947 res2=00000001 errno=0
+func=rred op1=7c47939b.f1ef50a5 result=3ccd4e28.ce0072bc.f77 res2=00000003 errno=0
+func=rred op1=7c49597b.4100e258 result=bcb64320.488cff01.a5f res2=00000001 errno=0
+func=rred op1=7c5163dc.d0e3814d result=3c72e99f.5d9c32f1.ff8 res2=00000003 errno=0
+func=rred op1=7c5c97fa.80bb3342 result=bcdc6b35.559d2059.9f7 res2=00000003 errno=0
+func=rred op1=7c67ba3b.a123b9e3 result=bcb3e5ec.5cd978a3.660 res2=00000003 errno=0
+func=rred op1=7c6c715a.d186ca04 result=3cbafd88.1ff40bbe.25d res2=00000003 errno=0
+func=rred op1=7c748f0c.39039d98 result=bcb188b8.7125f245.261 res2=00000001 errno=0
+func=rred op1=7c7f9c8a.39a6e64f result=3cbfb7ef.f75b187a.a5c res2=00000003 errno=0
+func=rred op1=7c888033.854533ce result=3cc2392b.e761129b.92d res2=00000003 errno=0
+func=rred op1=7c8bab62.ed655019 result=bca027d1.84afb198.4ca res2=00000001 errno=0
+func=rred op1=7c96879f.df2468b3 result=3c760e6e.c7640acd.975 res2=00000001 errno=0
+func=rred op1=7c99b2cf.474484fe result=bcd5eae6.8d6f6ed6.6fa res2=00000001 errno=0
+func=rred op1=7ca3f5be.5803f500 result=3cb44a86.4a12739e.d90 res2=00000001 errno=0
+func=rred op1=7ca91981.6644dc66 result=bcad8dd5.3072e1d6.e65 res2=00000003 errno=0
+func=rred op1=7cb1b083.c1635599 result=bcd53a73.17344e80.02e res2=00000003 errno=0
+func=rred op1=7cbdf09d.8405ef80 result=3cce6fc9.6f1bad6e.458 res2=00000003 errno=0
+func=rred op1=7cc18a30.49236b73 result=bca2869d.ccc0dc70.1aa res2=00000003 errno=0
+func=rred op1=7ccb850f.752565f3 result=3cbf51bd.adc47905.a4b res2=00000001 errno=0
+func=rred op1=7cd408e8.1423ea13 result=3c7c3e87.d51972eb.e58 res2=00000003 errno=0
+func=rred op1=7cdb9839.31455b06 result=bcd87b33.9dee44ef.301 res2=00000001 errno=0
+func=rred op1=7ce2c98c.2ea3aac3 result=bcb0c2b5.4f6f4541.5c5 res2=00000001 errno=0
+func=rred op1=7ce54843.f9a42963 result=3cb7d257.44b5a1fc.55b res2=00000003 errno=0
+func=rred op1=7cf3693a.2163ca6b result=bcaa75c8.a9982dc7.bf4 res2=00000003 errno=0
+func=rred op1=7cf4a896.06e409bb result=3cbb5a28.3f58d059.d26 res2=00000001 errno=0
+func=rred op1=7d03b911.1ac3da3f result=bc98ad09.7e16e8a3.990 res2=00000003 errno=0
+func=rred op1=7d0458bf.0d83f9e7 result=3cc134e5.1a4f968a.65e res2=00000001 errno=0
+func=rred op1=7d139125.9e13d255 result=bcc05085.848ef3f8.52c res2=00000001 errno=0
+func=rred op1=7d13e0fc.9773e229 result=3c9fd006.2c1bfd34.321 res2=00000003 errno=0
+func=rred op1=7d23cd06.d91bde34 result=bc918a0c.d011d412.ffe res2=00000001 errno=0
+func=rred op1=7d23f4f2.55cbe61e result=3cc21944.b010391c.790 res2=00000003 errno=0
+func=rred op1=7d3db38a.45a9cd4e result=bcaa4f13.381abe1c.7fd res2=00000003 errno=0
+func=rred op1=7d3dc780.0401d143 result=3cbb6d82.f817882f.721 res2=00000001 errno=0
+func=rred op1=7d48c048.8f62d5c1 result=bcb5ec90.04164917.bfe res2=00000001 errno=0
+func=rred op1=7d48d43e.4dbad9b6 result=3ccd9ec4.9219c2b1.d21 res2=00000001 errno=0
+func=rred op1=7d51496b.1ecc6073 result=bcdbf6eb.e51a4067.28f res2=00000003 errno=0
+func=rred op1=7d5b43e4.49b25382 result=3cc0773a.f60c63a3.922 res2=00000003 errno=0
+func=rred op1=7d629533.db20214e result=3caec8d2.380de668.48d res2=00000003 errno=0
+func=rred op1=7d678875.916718db result=bc812d1d.a05706f6.dbd res2=00000003 errno=0
+func=rred op1=7d73311d.5a1dffc1 result=bccb61e5.12202e8b.ed9 res2=00000003 errno=0
+func=rred op1=7d7bdfcd.c8b031f5 result=3cc7169d.aa0a6cce.36a res2=00000001 errno=0
+func=rred op1=7d806987.bf7b94c1 result=3ca63243.67e262ec.dae res2=00000001 errno=0
+func=rred op1=7d8ea763.63529cf5 result=bcbc463f.5448386d.495 res2=00000003 errno=0
+func=rred op1=7d93f8fe.a87156ce result=3c841497.1e2d6fd7.fc3 res2=00000001 errno=0
+func=rred op1=7d9b17ec.7a5cdae8 result=bcc26e67.1239ddf4.5ba res2=00000003 errno=0
+func=rred op1=7da11b6d.26242f81 result=bcd30f0b.cb2b4973.1b8 res2=00000001 errno=0
+func=rred op1=7dadf57d.fcaa0235 result=3c9e1ee2.ad4427c3.fa5 res2=00000003 errno=0
+func=rred op1=7db72f82.de12cb7b result=3cc9f61f.bd8ae7e5.5a3 res2=00000003 errno=0
+func=rred op1=7dbabef9.c7088d88 result=bcbad282.955d03fc.b92 res2=00000003 errno=0
+func=rred op1=7dc09601.1925bb71 result=3ccc78b2.a15095e0.59b res2=00000001 errno=0
+func=rred op1=7dc75bfc.37bcf22b result=bcb0c837.06464c10.bb0 res2=00000003 errno=0
+func=rred op1=7dd0ac3d.c5facec9 result=bc9af7ad.dcbe5092.f3b res2=00000003 errno=0
+func=rred op1=7ddaa8bd.1a337a30 result=3caaad57.4dfbb766.7e9 res2=00000003 errno=0
+func=rred op1=7de750dd.e152687f result=3ccabfec.f1ac5db1.9bd res2=00000003 errno=0
+func=rred op1=7dee009c.53148be1 result=bc4295a3.b0a64b1d.494 res2=00000001 errno=0
+func=rred op1=7df3fe8d.d3a69ba4 result=3cc40201.7a7cc98c.dee res2=00000001 errno=0
+func=rred op1=7df7566d.0c87ad55 result=bcab4204.6b80e9bf.68d res2=00000003 errno=0
+func=rred op1=7e00a976.30602c5e result=3cd0ac56.90bd52a0.0f1 res2=00000003 errno=0
+func=rred op1=7e0aab84.afce1c9b result=bcabd6b1.89061c18.532 res2=00000001 errno=0
+func=rred op1=7e1c5610.8171543e result=bcad000b.c41080ca.27b res2=00000001 errno=0
+func=rred op1=7e1fab28.24b7c384 result=3ca85aa2.d7e6ee02.d56 res2=00000003 errno=0
+func=rred op1=7e21801f.e3ff1965 result=3cc36d54.5cf79733.f4a res2=00000001 errno=0
+func=rred op1=7e2ed746.06b378e8 result=bcecc7ae.98ff589f.963 res2=00000001 errno=0
+func=rred op1=7e3615d2.49e69b00 result=bcb0d2ba.581d09c8.bd0 res2=00000001 errno=0
+func=rred op1=7e37c05e.1b89d2a3 result=3cc243fa.21ed3282.200 res2=00000001 errno=0
+func=rred op1=7e42f5b3.2e213e61 result=3c9e1fa1.ff2790e8.618 res2=00000003 errno=0
+func=rred op1=7e4935f1.65abf79f result=bcd2b4b4.780f82d7.432 res2=00000001 errno=0
+func=rred op1=7e555b08.a4d58882 result=3cd425f4.41dfab90.a62 res2=00000001 errno=0
+func=rred op1=7e587b27.c09ae521 result=bc7c2e95.88941548.c44 res2=00000003 errno=0
+func=rred op1=7e65b86d.775e11c1 result=3caa99cf.4e150e3f.48f res2=00000001 errno=0
+func=rred op1=7e6b3de2.09d7b881 result=bcb4588d.092f8c71.d59 res2=00000003 errno=0
+func=rred op1=7e7719ca.9bfc7b71 result=3ca38e29.ebf008ed.17e res2=00000003 errno=0
+func=rred op1=7e79dc84.e5394ed1 result=bcb7de5f.ba420f1a.ee1 res2=00000001 errno=0
+func=rred op1=7e87ca79.2e4bb049 result=3c85db7c.9e97f922.d73 res2=00000003 errno=0
+func=rred op1=7e892bd6.52ea19f9 result=bcbeea05.1c67146d.1f2 res2=00000001 errno=0
+func=rred op1=7e977221.e52415dd result=3cb64999.7fc30811.72d res2=00000001 errno=0
+func=rred op1=7e9822d0.77734ab5 result=bca6b7b6.60ee1700.0e7 res2=00000003 errno=0
+func=rred op1=7ea79e4d.89b7e313 result=3cbbc078.a769065a.289 res2=00000003 errno=0
+func=rred op1=7ea7f6a4.d2df7d7f result=bc9793f0.234434dd.45b res2=00000001 errno=0
+func=rred op1=7eb7e08f.009596e4 result=3c942309.19ebbd68.68a res2=00000001 errno=0
+func=rred op1=7eb80cba.a529641a result=bcbc9cb2.69bf2437.5fe res2=00000003 errno=0
+func=rred op1=7ec0145e.ee260882 result=bd1927f4.7b11a2ef.b32 res2=00000001 errno=0
+func=rred op1=7ecfef00.89e2d917 result=3d17e4bf.273698fa.830 res2=00000001 errno=0
+func=rred op1=7ed1e86b.4070312b result=3cae348d.a6e19c1c.9d0 res2=00000003 errno=0
+func=rred op1=7eddeec8.9304e338 result=bcc50f8f.0006bd30.38a res2=00000001 errno=0
+func=rred op1=7ee4d972.375df0ba result=3cd9a20e.53742ca6.6ad res2=00000003 errno=0
+func=rred op1=7eeae7ab.c9cd3d0e result=bcb5fc14.e621bcf8.089 res2=00000001 errno=0
+func=rred op1=7ef36bf9.a50c0440 result=bc7d90bc.c35ff8f9.fe4 res2=00000001 errno=0
+func=rred op1=7ef9641d.653169f9 result=3cb249fd.4db5bdd8.c8c res2=00000001 errno=0
+func=rred op1=7f05a644.52d0cd92 result=3cd3acc6.26de3d84.80b res2=00000001 errno=0
+func=rred op1=7f0d21f6.77920660 result=bc962c8d.9287fabb.7eb res2=00000003 errno=0
+func=rred op1=7f1846f8.0e4f0550 result=bca27a75.fa1bfb9c.3ee res2=00000001 errno=0
+func=rred op1=7f1e3f1b.ce746b09 result=3cd1d3ba.5aa83df4.e0d res2=00000001 errno=0
+func=rred op1=7f20fe7a.706a83b8 result=bca9dea5.2af3f9da.be7 res2=00000003 errno=0
+func=rred op1=7f2bd19c.99d2ea81 result=3ce20edb.d42efde6.d4c res2=00000001 errno=0
+func=rred op1=7f32353a.0abb43fc result=bcbbb7b0.f729f96a.5e5 res2=00000003 errno=0
+func=rred op1=7f3f75db.68c52b4d result=3cf1b629.9de4ddfb.e6d res2=00000001 errno=0
+func=rred op1=7f40631a.a3422396 result=bcc8f21f.44d8fa12.ee8 res2=00000003 errno=0
+func=rred op1=7f4eda7b.9b9ccb2b result=3d01c4f1.fc468df8.63d res2=00000001 errno=0
+func=rred op1=7f50156a.bcadf385 result=bcd87bdc.51cb7a2f.068 res2=00000001 errno=0
+func=rred op1=7f5fc38b.4f595b5e result=3d11aec5.6eb405fd.a85 res2=00000001 errno=0
+func=rred op1=7f60490f.d1af395b result=bd17cdbc.8326e489.69f res2=00000003 errno=0
+func=rred op1=7f6ff730.645aa134 result=3d0d3e93.c8f52d6f.8f0 res2=00000003 errno=0
+func=rred op1=7f702f3d.472e9670 result=bd1add38.0d6053cf.4ac res2=00000001 errno=0
+func=rred op1=7f7fc353.0847140e result=3d013bc7.19963049.ffb res2=00000003 errno=0
+func=rred op1=7f8b1c15.d78e7c7c result=3c920cfc.515a2cbc.5ee res2=00000003 errno=0
+func=rred op1=7f8b69c5.be22ac8d result=bca48a3e.9ab2e29b.cec res2=00000003 errno=0
+func=rred op1=7f90493a.06fceed7 result=bcf05936.3ca09359.ad8 res2=00000003 errno=0
+func=rred op1=7f9fdd33.a48c48cd result=3d0b3778.faf716ae.f8a res2=00000001 errno=0
+func=rred op1=7fa45510.61aadd5d result=3cab137a.7a07431a.8e6 res2=00000001 errno=0
+func=rred op1=7fa4a2c0.483f0d6e result=bcc6cbde.24de2833.5aa res2=00000001 errno=0
+func=rred op1=7fb0cab5.b36ef5c5 result=3cd46c6d.3b1c2a77.dcc res2=00000003 errno=0
+func=rred op1=7fbea670.85ca6414 result=bcb28441.cfb50d4c.26e res2=00000003 errno=0
+func=rred op1=7fc61a3d.b8c8d129 result=bc5dd15f.96b823f1.fc1 res2=00000003 errno=0
+func=rred op1=7fcce143.2eac7048 result=3cb195b6.d2ff4c2c.96f res2=00000003 errno=0
+func=rred op1=7fd537a7.0d39d743 result=3ccad7d7.bad9d2d2.aa6 res2=00000003 errno=0
+func=rred op1=7fddc3d9.da3b6a2e result=bcb372cc.cc6ace6b.b6c res2=00000001 errno=0
+func=rred op1=7fe68b89.0e904e1c result=bccc3da8.35ea7482.024 res2=00000003 errno=0
+func=rred op1=7fed528e.8473ed3b result=3caf7141.b32793da.ee7 res2=00000003 errno=0
diff --git a/math/test/testcases/directed/sincosf.tst b/test/testcases/directed/sincosf.tst
index b4b2526..b4b2526 100644
--- a/math/test/testcases/directed/sincosf.tst
+++ b/test/testcases/directed/sincosf.tst
diff --git a/math/test/testcases/directed/sinf.tst b/test/testcases/directed/sinf.tst
index 13cfdca..13cfdca 100644
--- a/math/test/testcases/directed/sinf.tst
+++ b/test/testcases/directed/sinf.tst
diff --git a/math/test/testcases/random/double.tst b/test/testcases/random/double.tst
index c37e837..4306259 100644
--- a/math/test/testcases/random/double.tst
+++ b/test/testcases/random/double.tst
@@ -3,6 +3,7 @@
!! Copyright (c) 1999-2018, Arm Limited.
!! SPDX-License-Identifier: MIT
+test rred 10000
test exp 10000
test exp2 10000
test log 10000
diff --git a/math/test/testcases/random/float.tst b/test/testcases/random/float.tst
index baf62b9..baf62b9 100644
--- a/math/test/testcases/random/float.tst
+++ b/test/testcases/random/float.tst
diff --git a/math/test/traces/exp.txt b/test/traces/exp.txt
index cb067d5..cb067d5 100644
--- a/math/test/traces/exp.txt
+++ b/test/traces/exp.txt
diff --git a/math/test/traces/sincosf.txt b/test/traces/sincosf.txt
index 33de0c7..33de0c7 100644
--- a/math/test/traces/sincosf.txt
+++ b/test/traces/sincosf.txt