summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorAllen Webb <allenwebb@google.com>2018-02-22 11:13:03 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-03-05 18:34:40 -0800
commit6719bdf3edef357c1a81e8ed48728b68e0ec0431 (patch)
treefb3722081274aa3737aa60cb71ddaf134598f0e7 /core
parent38c86d9d1eb5388d0bac925387a23a5a793da7b1 (diff)
downloadchrome-ec-6719bdf3edef357c1a81e8ed48728b68e0ec0431.tar.gz
Cr50: Add LLSR (long long shift right) support.
Cr50 lacks native instructions for 64-bit integers and an ABI function can be used by the compiler to take the place of the needed instructions. This CL adds support for a right bitwise shift of 64-bit integers. BRANCH=none BUG=chromium:794010 TEST=Set CONFIG_LLSR_TEST, build, update cr50, and run llsrtest on the console. Change-Id: Iae66c86720c531454ba29f15b3cc6a07959f5ef2 Signed-off-by: Allen Webb <allenwebb@google.com> Reviewed-on: https://chromium-review.googlesource.com/931932 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'core')
-rw-r--r--core/cortex-m/build.mk2
-rw-r--r--core/cortex-m/llsr.c65
2 files changed, 66 insertions, 1 deletions
diff --git a/core/cortex-m/build.mk b/core/cortex-m/build.mk
index cc323a2dca..5d035a43cd 100644
--- a/core/cortex-m/build.mk
+++ b/core/cortex-m/build.mk
@@ -22,7 +22,7 @@ CFLAGS_CPU+=-flto
LDFLAGS_EXTRA+=-flto
endif
-core-y=cpu.o init.o ldivmod.o uldivmod.o
+core-y=cpu.o init.o ldivmod.o llsr.o uldivmod.o
core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o
core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o
core-$(CONFIG_WATCHDOG)+=watchdog.o
diff --git a/core/cortex-m/llsr.c b/core/cortex-m/llsr.c
new file mode 100644
index 0000000000..5a43dc1f08
--- /dev/null
+++ b/core/cortex-m/llsr.c
@@ -0,0 +1,65 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Enable the use of right shift for uint64_t. */
+
+#include <console.h>
+#include <compile_time_macros.h>
+#include <stdint.h>
+
+union words {
+ uint64_t u64;
+ uint32_t w[2];
+};
+
+uint64_t __aeabi_llsr(uint64_t v, uint32_t shift)
+{
+ union words val;
+ union words res;
+
+ val.u64 = v;
+ res.w[1] = val.w[1] >> shift;
+ res.w[0] = val.w[0] >> shift;
+ res.w[0] |= val.w[1] >> (shift - 32); /* Handle shift >= 32*/
+ res.w[0] |= val.w[1] << (32 - shift); /* Handle shift <= 32*/
+ return res.u64;
+}
+
+#ifdef CONFIG_LLSR_TEST
+
+static int command_llsr(int argc, char **argv)
+{
+ /* Volatile to prevent compilier optimization from interfering. */
+ volatile uint64_t start = 0x123456789ABCDEF0ull;
+ uint32_t x;
+
+ const struct {
+ uint32_t shift_by;
+ uint64_t result;
+ } cases[] = {
+ {0, start},
+ {16, 0x123456789ABCull},
+ {32, 0x12345678u},
+ {48, 0x1234u},
+ {64, 0u}
+ };
+
+ for (x = 0; x < ARRAY_SIZE(cases); ++x) {
+ if ((start >> cases[x].shift_by) != cases[x].result) {
+ ccprintf("FAILED %d\n", cases[x].shift_by);
+ return EC_ERROR_UNKNOWN;
+ }
+ }
+
+ ccprintf("SUCCESS\n");
+ return EC_SUCCESS;
+}
+
+DECLARE_CONSOLE_COMMAND(
+ llsrtest, command_llsr,
+ "",
+ "Run tests against the LLSR ABI. Prints SUCCESS or FAILURE.");
+
+#endif /* CONFIG_LLSR_TEST */