0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <stdlib.h>
0021 #include <stdio.h>
0022 #include <signal.h>
0023 #include <unistd.h>
0024
0025 #include <altivec.h>
0026
0027 #include "utils.h"
0028 #include "tm.h"
0029
0030 #define MAX_ATTEMPT 500000
0031
0032 #define NV_FPU_REGS 18
0033 #define FPR14 14
0034
0035 long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss);
0036
0037
0038 static double fps[] = {
0039
0040 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
0041
0042 -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18
0043 };
0044
0045 static sig_atomic_t fail, broken;
0046
0047 static void signal_usr1(int signum, siginfo_t *info, void *uc)
0048 {
0049 int i;
0050 ucontext_t *ucp = uc;
0051 ucontext_t *tm_ucp = ucp->uc_link;
0052
0053 for (i = 0; i < NV_FPU_REGS; i++) {
0054
0055 fail = (ucp->uc_mcontext.fp_regs[FPR14 + i] != fps[i]);
0056 if (fail) {
0057 broken = 1;
0058 printf("FPR%d (1st context) == %g instead of %g (expected)\n",
0059 FPR14 + i, ucp->uc_mcontext.fp_regs[FPR14 + i], fps[i]);
0060 }
0061 }
0062
0063 for (i = 0; i < NV_FPU_REGS; i++) {
0064
0065 fail = (tm_ucp->uc_mcontext.fp_regs[FPR14 + i] != fps[NV_FPU_REGS + i]);
0066 if (fail) {
0067 broken = 1;
0068 printf("FPR%d (2nd context) == %g instead of %g (expected)\n",
0069 FPR14 + i, tm_ucp->uc_mcontext.fp_regs[FPR14 + i], fps[NV_FPU_REGS + i]);
0070 }
0071 }
0072 }
0073
0074 static int tm_signal_context_chk_fpu()
0075 {
0076 struct sigaction act;
0077 int i;
0078 long rc;
0079 pid_t pid = getpid();
0080
0081 SKIP_IF(!have_htm());
0082 SKIP_IF(htm_is_synthetic());
0083
0084 act.sa_sigaction = signal_usr1;
0085 sigemptyset(&act.sa_mask);
0086 act.sa_flags = SA_SIGINFO;
0087 if (sigaction(SIGUSR1, &act, NULL) < 0) {
0088 perror("sigaction sigusr1");
0089 exit(1);
0090 }
0091
0092 i = 0;
0093 while (i < MAX_ATTEMPT && !broken) {
0094
0095
0096
0097
0098
0099
0100 rc = tm_signal_self_context_load(pid, NULL, fps, NULL, NULL);
0101 FAIL_IF(rc != pid);
0102 i++;
0103 }
0104
0105 return (broken);
0106 }
0107
0108 int main(void)
0109 {
0110 return test_harness(tm_signal_context_chk_fpu, "tm_signal_context_chk_fpu");
0111 }