unaligned_load: Fix sign extension, add test case for sign extension
H/T to @foogod again for this.
This commit is contained in:
parent
5a9590cdff
commit
8a088f73db
2 changed files with 25 additions and 5 deletions
|
@ -138,7 +138,7 @@ DoubleExceptionLoadStoreHandler:
|
|||
a3 holds raw value, a4 holds masked */
|
||||
bbsi a5, 15, .Lafter_extend_sign /* 16-bit unsigned, no sign extension */
|
||||
bbci a3, 15, .Lafter_extend_sign /* sign bit not set, no sign extension */
|
||||
movi a3, 0xFFFF0000
|
||||
movi a3, 0xFFFF8000
|
||||
or a4, a3, a4 /* set 32-bit sign bits */
|
||||
j .Lafter_extend_sign
|
||||
|
||||
|
|
|
@ -68,7 +68,11 @@ void test_naive_strcpy(const char *string)
|
|||
void test_l16si(const char *string)
|
||||
{
|
||||
/* This follows most of the l16si path, but as the
|
||||
values in the string are all 7 bit none of them get sign extended */
|
||||
values in the string are all 7 bit none of them get sign extended.
|
||||
|
||||
See separate test_sign_extension function which validates
|
||||
sign extension works as expected.
|
||||
*/
|
||||
int16_t *src_int16 = (int16_t *)string;
|
||||
int32_t *dst_int32 = (int32_t *)buf;
|
||||
dst_int32[0] = src_int16[0];
|
||||
|
@ -119,7 +123,8 @@ void test_string(const char *string, char *label, bool evict_cache)
|
|||
run_test(string, test_l16si, "load as l16si", nullvalue, evict_cache);
|
||||
}
|
||||
|
||||
static void test_doubleexceptions();
|
||||
static void test_doubleexception();
|
||||
static void test_sign_extension();
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
|
@ -134,7 +139,8 @@ void user_init(void)
|
|||
test_string(iromtest, "Cached flash", 0);
|
||||
test_string(iromtest, "'Uncached' flash", 1);
|
||||
|
||||
test_doubleexceptions();
|
||||
test_doubleexception();
|
||||
test_sign_extension();
|
||||
}
|
||||
|
||||
static volatile bool frc1_ran;
|
||||
|
@ -149,7 +155,7 @@ static void frc1_interrupt_handler(void)
|
|||
frc1_finished = true;
|
||||
}
|
||||
|
||||
static void test_doubleexceptions()
|
||||
static void test_doubleexception()
|
||||
{
|
||||
printf("Testing DoubleException behaviour...\r\n");
|
||||
timer_set_interrupts(FRC1, false);
|
||||
|
@ -169,3 +175,17 @@ static void test_doubleexceptions()
|
|||
else
|
||||
printf("PASSED\r\n");
|
||||
}
|
||||
|
||||
const volatile __attribute__((section(".iram1.notliterals"))) int16_t unsigned_shorts[] = { -3, -4, -5, -32767, 44 };
|
||||
|
||||
static void test_sign_extension()
|
||||
{
|
||||
/* this step seems to be necessary so the compiler will actually generate l16si */
|
||||
int16_t *shorts_p = (int16_t *)unsigned_shorts;
|
||||
if(shorts_p[0] == -3 && shorts_p[1] == -4 && shorts_p[2] == -5 && shorts_p[3] == -32767 && shorts_p[4] == 44)
|
||||
{
|
||||
printf("l16si sign extension worked as expected.\r\n");
|
||||
} else {
|
||||
printf("l16si sign extension failed. Got values %d %d %d %d %d\r\n", shorts_p[0], shorts_p[1], shorts_p[2], shorts_p[3], shorts_p[4]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue