blob: 27d917de6f87c4b433edc2592ab06f700114e6da [file] [log] [blame]
/* Copyright (c) 2014 The Regents of the University of California
* Kevin Klues <klueska@cs.berkeley.edu>
* See LICENSE for details.
*
* xmm_test: test the reading/writing of the xmm registers */
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <parlib/pvcalarm.h>
static void nothing() {}
static void read_xmm(int id)
{
char array[16*16] __attribute__((aligned(128))) = {0};
asm volatile (
"movdqa %%xmm0, %0;"
"movdqa %%xmm1, %1;"
"movdqa %%xmm2, %2;"
"movdqa %%xmm3, %3;"
"movdqa %%xmm4, %4;"
"movdqa %%xmm5, %5;"
"movdqa %%xmm6, %6;"
"movdqa %%xmm7, %7;"
"movdqa %%xmm8, %8;"
"movdqa %%xmm9, %9;"
"movdqa %%xmm10, %10;"
"movdqa %%xmm11, %11;"
"movdqa %%xmm12, %12;"
"movdqa %%xmm13, %13;"
"movdqa %%xmm14, %14;"
"movdqa %%xmm15, %15;"
:"=m"(array[0*16]),
"=m"(array[1*16]),
"=m"(array[2*16]),
"=m"(array[3*16]),
"=m"(array[4*16]),
"=m"(array[5*16]),
"=m"(array[6*16]),
"=m"(array[7*16]),
"=m"(array[8*16]),
"=m"(array[9*16]),
"=m"(array[10*16]),
"=m"(array[11*16]),
"=m"(array[12*16]),
"=m"(array[13*16]),
"=m"(array[14*16]),
"=m"(array[15*16])
:
:
);
for (int i=0; i<16; i++) {
int *addr = (int*)(array + i*16);
if (*addr != id) {
printf("ERROR: xmm%d, id: %d, *addr: %d\n",
i, id, *addr);
abort();
}
}
}
static void write_xmm(int __id)
{
char id[16] __attribute__((aligned(128)));
*((int*)id) = __id;
asm volatile (
"movdqa %0, %%xmm0;"
"movdqa %0, %%xmm1;"
"movdqa %0, %%xmm2;"
"movdqa %0, %%xmm3;"
"movdqa %0, %%xmm4;"
"movdqa %0, %%xmm5;"
"movdqa %0, %%xmm6;"
"movdqa %0, %%xmm7;"
"movdqa %0, %%xmm8;"
"movdqa %0, %%xmm9;"
"movdqa %0, %%xmm10;"
"movdqa %0, %%xmm11;"
"movdqa %0, %%xmm12;"
"movdqa %0, %%xmm13;"
"movdqa %0, %%xmm14;"
"movdqa %0, %%xmm15;"
:
:"m"(id[0])
:"%xmm0","%xmm1","%xmm2","%xmm3",
"%xmm4","%xmm5","%xmm6","%xmm7",
"%xmm8","%xmm9","%xmm10","%xmm11",
"%xmm12","%xmm13","%xmm14","%xmm15"
);
}
void *worker_thread(void* arg)
{
write_xmm((int)(long)arg);
while (1)
read_xmm((int)(long)arg);
return 0;
}
int main(int argc, char** argv)
{
#define NUM_THREADS 1000
pthread_t children[NUM_THREADS];
enable_pvcalarms(PVCALARM_REAL, 10000, nothing);
for (int i=0; i<NUM_THREADS; i++)
pthread_create(&children[i], NULL, &worker_thread,
(void*)(long)i + 2);
worker_thread((void*)(long)1);
return 0;
}