|  | /* 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; | 
|  | } | 
|  |  |