📄 try.c
字号:
e->d[i].p = (mp_ptr) ((char *) (e->d[i].region.ptr + e->d[i].region.size) - d[i].size - d[i].align); } else { e->d[i].p = e->d[i].region.ptr + e->d[i].region.size - d[i].size - d[i].align; if (tr->overlap == OVERLAP_LOW_TO_HIGH) e->d[i].p -= offset; } } else { if (tr->dst_bytes[i]) { e->d[i].p = (mp_ptr) ((char *) e->d[i].region.ptr + d[i].align); } else { e->d[i].p = e->d[i].region.ptr + d[i].align; if (tr->overlap == OVERLAP_HIGH_TO_LOW) e->d[i].p += offset; } } } /* establish e->s[].p sources */ for (i = 0; i < NUM_SOURCES; i++) { int o = overlap->s[i]; switch (o) { case -1: /* no overlap */ e->s[i].p = s[i].p; break; case 0: case 1: /* overlap with d[o] */ if (tr->overlap == OVERLAP_HIGH_TO_LOW) e->s[i].p = e->d[o].p - s[i].align; else if (tr->overlap == OVERLAP_LOW_TO_HIGH) e->s[i].p = e->d[o].p + s[i].align; else if (tr->size2 == SIZE_FRACTION) e->s[i].p = e->d[o].p + size2; else e->s[i].p = e->d[o].p; break; default: abort(); break; } }}voidvalidate_fail (void){ if (tr->reference) { trap_location = TRAP_REF; call (&ref, tr->reference); trap_location = TRAP_NOWHERE; } print_all(); abort();}voidtry_one (void){ int i; if (option_spinner) spinner(); spinner_count++; trap_location = TRAP_SETUPS; if (tr->divisor == DIVISOR_NORM) divisor |= GMP_NUMB_HIGHBIT; if (tr->divisor == DIVISOR_ODD) divisor |= 1; for (i = 0; i < NUM_SOURCES; i++) { if (s[i].high) s[i].p = s[i].region.ptr + s[i].region.size - SRC_SIZE(i) - s[i].align; else s[i].p = s[i].region.ptr + s[i].align; } pointer_setup (&ref); pointer_setup (&fun); for (i = 0; i < NUM_DESTS; i++) { if (! tr->dst[i]) continue; if (tr->dst0_from_src1 && i==0) { t_random (s[1].region.ptr, d[0].size); MPN_COPY (fun.d[0].p, s[1].region.ptr, d[0].size); MPN_COPY (ref.d[0].p, s[1].region.ptr, d[0].size); } else if (tr->dst_bytes[i]) { memset (ref.d[i].p, 0xBA, d[i].size); memset (fun.d[i].p, 0xBA, d[i].size); } else { refmpn_fill (ref.d[i].p, d[i].size, DEADVAL); refmpn_fill (fun.d[i].p, d[i].size, DEADVAL); } } ref.retval = 0x04152637; fun.retval = 0x8C9DAEBF; for (i = 0; i < NUM_SOURCES; i++) { if (! tr->src[i]) continue; mprotect_region (&s[i].region, PROT_READ|PROT_WRITE); t_random (s[i].p, SRC_SIZE(i)); switch (tr->data) { case DATA_NON_ZERO: if (refmpn_zero_p (s[i].p, SRC_SIZE(i))) s[i].p[0] = 1; break; case DATA_MULTIPLE_DIVISOR: /* same number of low zero bits as divisor */ s[i].p[0] &= ~ LOW_ZEROS_MASK (divisor); refmpn_sub_1 (s[i].p, s[i].p, size, refmpn_mod_1 (s[i].p, size, divisor)); break; case DATA_GCD: /* s[1] no more bits than s[0] */ if (i == 1 && size2 == size) s[1].p[size-1] &= refmpn_msbone_mask (s[0].p[size-1]); /* high limb non-zero */ s[i].p[SRC_SIZE(i)-1] += (s[i].p[SRC_SIZE(i)-1] == 0); /* odd */ s[i].p[0] |= 1; break; case DATA_SRC1_ODD: if (i == 1) s[i].p[0] |= 1; break; case DATA_SRC1_HIGHBIT: if (i == 1) { if (tr->size2) s[i].p[size2-1] |= GMP_NUMB_HIGHBIT; else s[i].p[size-1] |= GMP_NUMB_HIGHBIT; } break; case DATA_UDIV_QRNND: s[i].p[1] %= divisor; break; } mprotect_region (&s[i].region, PROT_READ); if (ref.s[i].p != s[i].p) { refmpn_copyi (ref.s[i].p, s[i].p, SRC_SIZE(i)); refmpn_copyi (fun.s[i].p, s[i].p, SRC_SIZE(i)); } } if (option_print) print_all(); if (tr->validate != NULL) { trap_location = TRAP_FUN; call (&fun, choice->function); trap_location = TRAP_NOWHERE; if (! CALLING_CONVENTIONS_CHECK ()) { print_all(); abort(); } (*tr->validate) (); } else { trap_location = TRAP_REF; call (&ref, tr->reference); trap_location = TRAP_FUN; call (&fun, choice->function); trap_location = TRAP_NOWHERE; if (! CALLING_CONVENTIONS_CHECK ()) { print_all(); abort(); } compare (); }}#define SIZE_ITERATION \ for (size = MAX3 (option_firstsize, \ choice->minsize, \ (tr->size == SIZE_ALLOW_ZERO) ? 0 : 1); \ size <= option_lastsize; \ size++)#define SIZE2_FIRST \ (tr->size2 == SIZE_2 ? 2 \ : tr->size2 == SIZE_FRACTION ? 0 \ : tr->size2 ? \ MAX (choice->minsize, (option_firstsize2 != 0 \ ? option_firstsize2 : 1)) \ : 0)#define SIZE2_LAST \ (tr->size2 == SIZE_2 ? 2 \ : tr->size2 == SIZE_FRACTION ? FRACTION_COUNT-1 \ : tr->size2 ? size \ : 0)#define SIZE2_ITERATION \ for (size2 = SIZE2_FIRST; size2 <= SIZE2_LAST; size2++)#define ALIGN_COUNT(cond) ((cond) ? ALIGNMENTS : 1)#define ALIGN_ITERATION(w,n,cond) \ for (w[n].align = 0; w[n].align < ALIGN_COUNT(cond); w[n].align++)#define HIGH_LIMIT(cond) ((cond) != 0)#define HIGH_COUNT(cond) (HIGH_LIMIT (cond) + 1)#define HIGH_ITERATION(w,n,cond) \ for (w[n].high = 0; w[n].high <= HIGH_LIMIT(cond); w[n].high++)#define SHIFT_LIMIT \ ((unsigned long) (tr->shift ? GMP_NUMB_BITS -1 : 1))#define SHIFT_ITERATION \ for (shift = 1; shift <= SHIFT_LIMIT; shift++)voidtry_many (void){ int i; { unsigned long total = 1; total *= option_repetitions; total *= option_lastsize; if (tr->size2 == SIZE_FRACTION) total *= FRACTION_COUNT; else if (tr->size2) total *= (option_lastsize+1)/2; total *= SHIFT_LIMIT; total *= MULTIPLIER_COUNT; total *= DIVISOR_COUNT; total *= CARRY_COUNT; total *= T_RAND_COUNT; total *= HIGH_COUNT (tr->dst[0]); total *= HIGH_COUNT (tr->dst[1]); total *= HIGH_COUNT (tr->src[0]); total *= HIGH_COUNT (tr->src[1]); total *= ALIGN_COUNT (tr->dst[0]); total *= ALIGN_COUNT (tr->dst[1]); total *= ALIGN_COUNT (tr->src[0]); total *= ALIGN_COUNT (tr->src[1]); total *= OVERLAP_COUNT; printf ("%s %lu\n", choice->name, total); } spinner_count = 0; for (i = 0; i < option_repetitions; i++) SIZE_ITERATION SIZE2_ITERATION SHIFT_ITERATION MULTIPLIER_ITERATION DIVISOR_ITERATION CARRY_ITERATION /* must be after divisor */ T_RAND_ITERATION HIGH_ITERATION(d,0, tr->dst[0]) HIGH_ITERATION(d,1, tr->dst[1]) HIGH_ITERATION(s,0, tr->src[0]) HIGH_ITERATION(s,1, tr->src[1]) ALIGN_ITERATION(d,0, tr->dst[0]) ALIGN_ITERATION(d,1, tr->dst[1]) ALIGN_ITERATION(s,0, tr->src[0]) ALIGN_ITERATION(s,1, tr->src[1]) OVERLAP_ITERATION try_one(); printf("\n");}/* Usually print_all() doesn't show much, but it might give a hint as to where the function was up to when it died. */voidtrap (int sig){ const char *name = "noname"; switch (sig) { case SIGILL: name = "SIGILL"; break;#ifdef SIGBUS case SIGBUS: name = "SIGBUS"; break;#endif case SIGSEGV: name = "SIGSEGV"; break; case SIGFPE: name = "SIGFPE"; break; } printf ("\n\nSIGNAL TRAP: %s\n", name); switch (trap_location) { case TRAP_REF: printf (" in reference function: %s\n", tr->reference_name); break; case TRAP_FUN: printf (" in test function: %s\n", choice->name); print_all (); break; case TRAP_SETUPS: printf (" in parameter setups\n"); print_all (); break; default: printf (" somewhere unknown\n"); break; } exit (1);}voidtry_init (void){#if HAVE_GETPAGESIZE /* Prefer getpagesize() over sysconf(), since on SunOS 4 sysconf() doesn't know _SC_PAGESIZE. */ pagesize = getpagesize ();#else#if HAVE_SYSCONF if ((pagesize = sysconf (_SC_PAGESIZE)) == -1) { /* According to the linux man page, sysconf doesn't set errno */ fprintf (stderr, "Cannot get sysconf _SC_PAGESIZE\n"); exit (1); }#elseError, error, cannot get page size#endif#endif printf ("pagesize is 0x%lX bytes\n", pagesize); signal (SIGILL, trap);#ifdef SIGBUS signal (SIGBUS, trap);#endif signal (SIGSEGV, trap); signal (SIGFPE, trap); { int i; for (i = 0; i < NUM_SOURCES; i++) { malloc_region (&s[i].region, 2*option_lastsize+ALIGNMENTS-1); printf ("s[%d] %p to %p (0x%lX bytes)\n", i, s[i].region.ptr, s[i].region.ptr + s[i].region.size, s[i].region.size * BYTES_PER_MP_LIMB); }#define INIT_EACH(e,es) \ for (i = 0; i < NUM_DESTS; i++) \ { \ malloc_region (&e.d[i].region, 2*option_lastsize+ALIGNMENTS-1); \ printf ("%s d[%d] %p to %p (0x%lX bytes)\n", \ es, i, e.d[i].region.ptr, \ e.d[i].region.ptr + e.d[i].region.size, \ e.d[i].region.size * BYTES_PER_MP_LIMB); \ } INIT_EACH(ref, "ref"); INIT_EACH(fun, "fun"); }}intstrmatch_wild (const char *pattern, const char *str){ size_t plen, slen; /* wildcard at start */ if (pattern[0] == '*') { pattern++; plen = strlen (pattern); slen = strlen (str); return (plen == 0 || (slen >= plen && memcmp (pattern, str+slen-plen, plen) == 0)); } /* wildcard at end */ plen = strlen (pattern); if (plen >= 1 && pattern[plen-1] == '*') return (memcmp (pattern, str, plen-1) == 0); /* no wildcards */ return (strcmp (pattern, str) == 0);}voidtry_name (const char *name){ int found = 0; int i; for (i = 0; i < numberof (choice_array); i++) { if (strmatch_wild (name, choice_array[i].name)) { choice = &choice_array[i]; tr = ¶m[choice->type]; try_many (); found = 1; } } if (!found) { printf ("%s unknown\n", name); /* exit (1); */ }}voidusage (const char *prog){ int col = 0; int i; printf ("Usage: %s [options] function...\n\ -1 use limb data 1,2,3,etc\n\ -9 use limb data all 0xFF..FFs\n\ -a zeros use limb data all zeros\n\ -a ffs use limb data all 0xFF..FFs (same as -9)\n\ -a 2fd use data 0x2FFF...FFFD\n\ -p print each case tried (try this if seg faulting)\n\ -R seed random numbers from time()\n\ -r reps set repetitions (default %d)\n\ -s size starting size to test\n\ -S size2 starting size2 to test\n\ -s s1-s2 range of sizes to test\n\ -W don't show the spinner (use this in gdb)\n\ -z disable mprotect() redzones\n\Default data is refmpn_random() and refmpn_random2().\n\\n\Functions that can be tested:\n\", prog, DEFAULT_REPETITIONS); for (i = 0; i < numberof (choice_array); i++) { if (col + 1 + strlen (choice_array[i].name) > 79) { printf ("\n"); col = 0; } printf (" %s", choice_array[i].name); col += 1 + strlen (choice_array[i].name); } printf ("\n"); exit(1);}intmain (int argc, char *argv[]){ int i; /* unbuffered output */ setbuf (stdout, NULL); setbuf (stderr, NULL); /* default trace in hex, and in upper-case so can paste into bc */ mp_trace_base = -16; param_init (); { unsigned seed = 123; int opt; while ((opt = getopt(argc, argv, "19a:b:pRr:S:s:Wz")) != EOF) { switch (opt) { case '1':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -