Skip to content

Commit

Permalink
Hexagon (tests/tcg/hexagon) TCG tests - atomics/load/store/misc
Browse files Browse the repository at this point in the history
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
Message-Id: <1612763186-18161-33-git-send-email-tsimpson@quicinc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
taylorsimpson authored and rth7680 committed Feb 18, 2021
1 parent dff2441 commit 825d6eb
Show file tree
Hide file tree
Showing 7 changed files with 1,147 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tests/tcg/hexagon/Makefile.target
Expand Up @@ -28,3 +28,18 @@ endif


CFLAGS += -Wno-incompatible-pointer-types -Wno-undefined-internal

HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon
VPATH += $(HEX_SRC)

first: $(HEX_SRC)/first.S
$(CC) -static -mv67 -nostdlib $^ -o $@

HEX_TESTS = first
HEX_TESTS += misc
HEX_TESTS += preg_alias
HEX_TESTS += dual_stores
HEX_TESTS += mem_noshuf
HEX_TESTS += atomics

TESTS += $(HEX_TESTS)
139 changes: 139 additions & 0 deletions tests/tcg/hexagon/atomics.c
@@ -0,0 +1,139 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <pthread.h>

/* Using volatile because we are testing atomics */
static inline int atomic_inc32(volatile int *x)
{
int old, dummy;
__asm__ __volatile__(
"1: %0 = memw_locked(%2)\n\t"
" %1 = add(%0, #1)\n\t"
" memw_locked(%2, p0) = %1\n\t"
" if (!p0) jump 1b\n\t"
: "=&r"(old), "=&r"(dummy)
: "r"(x)
: "p0", "memory");
return old;
}

/* Using volatile because we are testing atomics */
static inline long long atomic_inc64(volatile long long *x)
{
long long old, dummy;
__asm__ __volatile__(
"1: %0 = memd_locked(%2)\n\t"
" %1 = #1\n\t"
" %1 = add(%0, %1)\n\t"
" memd_locked(%2, p0) = %1\n\t"
" if (!p0) jump 1b\n\t"
: "=&r"(old), "=&r"(dummy)
: "r"(x)
: "p0", "memory");
return old;
}

/* Using volatile because we are testing atomics */
static inline int atomic_dec32(volatile int *x)
{
int old, dummy;
__asm__ __volatile__(
"1: %0 = memw_locked(%2)\n\t"
" %1 = add(%0, #-1)\n\t"
" memw_locked(%2, p0) = %1\n\t"
" if (!p0) jump 1b\n\t"
: "=&r"(old), "=&r"(dummy)
: "r"(x)
: "p0", "memory");
return old;
}

/* Using volatile because we are testing atomics */
static inline long long atomic_dec64(volatile long long *x)
{
long long old, dummy;
__asm__ __volatile__(
"1: %0 = memd_locked(%2)\n\t"
" %1 = #-1\n\t"
" %1 = add(%0, %1)\n\t"
" memd_locked(%2, p0) = %1\n\t"
" if (!p0) jump 1b\n\t"
: "=&r"(old), "=&r"(dummy)
: "r"(x)
: "p0", "memory");
return old;
}

#define LOOP_CNT 1000
/* Using volatile because we are testing atomics */
volatile int tick32 = 1;
/* Using volatile because we are testing atomics */
volatile long long tick64 = 1;
int err;

void *thread1_func(void *arg)
{
int i;

for (i = 0; i < LOOP_CNT; i++) {
atomic_inc32(&tick32);
atomic_dec64(&tick64);
}
return NULL;
}

void *thread2_func(void *arg)
{
int i;
for (i = 0; i < LOOP_CNT; i++) {
atomic_dec32(&tick32);
atomic_inc64(&tick64);
}
return NULL;
}

void test_pthread(void)
{
pthread_t tid1, tid2;

pthread_create(&tid1, NULL, thread1_func, "hello1");
pthread_create(&tid2, NULL, thread2_func, "hello2");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);

if (tick32 != 1) {
printf("ERROR: tick32 %d != 1\n", tick32);
err++;
}
if (tick64 != 1) {
printf("ERROR: tick64 %lld != 1\n", tick64);
err++;
}
}

int main(int argc, char **argv)
{
test_pthread();
puts(err ? "FAIL" : "PASS");
return err;
}
60 changes: 60 additions & 0 deletions tests/tcg/hexagon/dual_stores.c
@@ -0,0 +1,60 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>

/*
* Make sure that two stores in the same packet honor proper
* semantics: slot 1 executes first, then slot 0.
* This is important when the addresses overlap.
*/
static inline void dual_stores(int *p, char *q, int x, char y)
{
asm volatile("{\n\t"
" memw(%0) = %2\n\t"
" memb(%1) = %3\n\t"
"}\n"
:: "r"(p), "r"(q), "r"(x), "r"(y)
: "memory");
}

typedef union {
int word;
char byte;
} Dual;

int err;

static void check(Dual d, int expect)
{
if (d.word != expect) {
printf("ERROR: 0x%08x != 0x%08x\n", d.word, expect);
err++;
}
}

int main()
{
Dual d;

d.word = ~0;
dual_stores(&d.word, &d.byte, 0x12345678, 0xff);
check(d, 0x123456ff);

puts(err ? "FAIL" : "PASS");
return err;
}
56 changes: 56 additions & 0 deletions tests/tcg/hexagon/first.S
@@ -0,0 +1,56 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#define SYS_write 64
#define SYS_exit_group 94
#define SYS_exit 93

#define FD_STDOUT 1

.type str,@object
.section .rodata
str:
.string "Hello!\n"
.size str, 8

.text
.global _start
_start:
r6 = #SYS_write
r0 = #FD_STDOUT
r1 = ##str
r2 = #7
trap0(#1)

r0 = #0
r6 = #SYS_exit_group
trap0(#1)

.section ".note.ABI-tag", "a"
.align 4
.long 1f - 0f /* name length */
.long 3f - 2f /* data length */
.long 1 /* note type */

/*
* vendor name seems like this should be MUSL but lldb doesn't agree.
*/
0: .asciz "GNU"
1: .align 4
2: .long 0 /* linux */
.long 3,0,0
3: .align 4

0 comments on commit 825d6eb

Please sign in to comment.