diff options
author | Allen Webb <allenwebb@google.com> | 2018-02-22 11:13:03 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-03-05 18:34:40 -0800 |
commit | 6719bdf3edef357c1a81e8ed48728b68e0ec0431 (patch) | |
tree | fb3722081274aa3737aa60cb71ddaf134598f0e7 /core/cortex-m/llsr.c | |
parent | 38c86d9d1eb5388d0bac925387a23a5a793da7b1 (diff) | |
download | chrome-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/cortex-m/llsr.c')
-rw-r--r-- | core/cortex-m/llsr.c | 65 |
1 files changed, 65 insertions, 0 deletions
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 */ |