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>
(cherry picked from commit 6719bdf3ed)
Reviewed-on: https://chromium-review.googlesource.com/969632
Commit-Queue: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Vadim Bendebury <vbendeb@chromium.org>
This commit is contained in:
Allen Webb 2018-02-22 11:13:03 -08:00 committed by ChromeOS Commit Bot
parent 8b1fab53c4
commit 79adbe8d41
3 changed files with 72 additions and 1 deletions

View File

@ -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

65
core/cortex-m/llsr.c Normal file
View File

@ -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 */

View File

@ -1749,6 +1749,12 @@
*/
#undef CONFIG_LIGHTBAR_TAP_DIM_LAST_SEGMENT
/*
* Adds a console command for testing the long long shift right ABI on Cortex-m4
* (Cr50).
*/
#undef CONFIG_LLSR_TEST
/* Program memory offset for little firmware loader. */
#undef CONFIG_LOADER_MEM_OFF