📄 try.c
字号:
printf ("%s %s\n", e->name, e == &ref ? tr->reference_name : choice->name); if (tr->retval) mpn_trace (" retval", &e->retval, 1); for (i = 0; i < NUM_DESTS; i++) { if (tr->dst[i]) { if (tr->dst_bytes[i]) byte_tracen (" d[%d]", i, e->d[i].p, d[i].size); else mpn_tracen (" d[%d]", i, e->d[i].p, d[i].size); printf (" located %p\n", e->d[i].p); } } for (i = 0; i < NUM_SOURCES; i++) if (tr->src[i]) printf (" s[%d] located %p\n", i, e->s[i].p);}voidprint_all (void){ int i; printf ("\n"); printf ("size %ld\n", size); if (tr->size2) printf ("size2 %ld\n", size2); for (i = 0; i < NUM_DESTS; i++) if (d[i].size != size) printf ("d[%d].size %ld\n", i, d[i].size); if (tr->multiplier) mpn_trace (" multiplier", &multiplier, 1); if (tr->divisor) mpn_trace (" divisor", &divisor, 1); if (tr->shift) printf (" shift %lu\n", shift); if (tr->carry) mpn_trace (" carry", &carry, 1); for (i = 0; i < NUM_DESTS; i++) if (tr->dst[i]) printf (" d[%d] %s, align %ld, size %ld\n", i, d[i].high ? "high" : "low", d[i].align, d[i].size); for (i = 0; i < NUM_SOURCES; i++) { if (tr->src[i]) { printf (" s[%d] %s, align %ld, ", i, s[i].high ? "high" : "low", s[i].align); switch (overlap->s[i]) { case -1: printf ("no overlap\n"); break; default: printf ("==d[%d]%s\n", overlap->s[i], tr->overlap == OVERLAP_LOW_TO_HIGH ? "+a" : tr->overlap == OVERLAP_HIGH_TO_LOW ? "-a" : ""); break; } printf (" s[%d]=", i); if (tr->carry_sign && (carry & (1 << i))) printf ("-"); mpn_trace (NULL, s[i].p, SRC_SIZE(i)); } } if (tr->dst0_from_src1) mpn_trace (" d[0]", s[1].region.ptr, size); if (tr->reference) print_each (&ref); print_each (&fun);}voidcompare (void){ int error = 0; int i; if (tr->retval && ref.retval != fun.retval) { printf ("Different return values (%lu, %lu)\n", ref.retval, fun.retval); error = 1; } for (i = 0; i < NUM_DESTS; i++) { switch (tr->dst_size[0]) { case SIZE_RETVAL: d[i].size = ref.retval; break; } } for (i = 0; i < NUM_DESTS; i++) { if (! tr->dst[i]) continue; if (tr->dst_bytes[i]) { if (memcmp (ref.d[i].p, fun.d[i].p, d[i].size) != 0) { printf ("Different d[%d] data results, low diff at %ld, high diff at %ld\n", i, byte_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size), byte_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size)); error = 1; } } else { if (d[i].size != 0 && ! refmpn_equal_anynail (ref.d[i].p, fun.d[i].p, d[i].size)) { printf ("Different d[%d] data results, low diff at %ld, high diff at %ld\n", i, mpn_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size), mpn_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size)); error = 1; } } } if (error) { print_all(); abort(); }}/* The functions are cast if the return value should be a long rather than the default mp_limb_t. This is necessary under _LONG_LONG_LIMB. This might not be enough if some actual calling conventions checking is implemented on a long long limb system. */voidcall (struct each_t *e, tryfun_t function){ switch (choice->type) { case TYPE_ADD: case TYPE_SUB: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, e->s[1].p, size2); break; case TYPE_ADD_N: case TYPE_SUB_N: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size); break; case TYPE_ADD_NC: case TYPE_SUB_NC: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size, carry); break; case TYPE_MUL_1: case TYPE_ADDMUL_1: case TYPE_SUBMUL_1: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, multiplier); break; case TYPE_MUL_1C: case TYPE_ADDMUL_1C: case TYPE_SUBMUL_1C: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, multiplier, carry); break; case TYPE_MUL_2: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, e->s[1].p); break; case TYPE_AND_N: case TYPE_ANDN_N: case TYPE_NAND_N: case TYPE_IOR_N: case TYPE_IORN_N: case TYPE_NIOR_N: case TYPE_XOR_N: case TYPE_XNOR_N: CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size); break; case TYPE_ADDSUB_N: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size); break; case TYPE_ADDSUB_NC: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size, carry); break; case TYPE_COPY: case TYPE_COPYI: case TYPE_COPYD: case TYPE_COM_N: CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size); break; case TYPE_DIVEXACT_BY3: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size); break; case TYPE_DIVEXACT_BY3C: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, carry); break; case TYPE_DIVMOD_1: case TYPE_DIVEXACT_1: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, divisor); break; case TYPE_DIVMOD_1C: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, divisor, carry); break; case TYPE_DIVREM_1: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, size2, e->s[0].p, size, divisor); break; case TYPE_DIVREM_1C: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, size2, e->s[0].p, size, divisor, carry); break; case TYPE_PREINV_DIVREM_1: { mp_limb_t dinv; unsigned shift; shift = refmpn_count_leading_zeros (divisor); dinv = refmpn_invert_limb (divisor << shift); e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, size2, e->s[0].p, size, divisor, dinv, shift); } break; case TYPE_MOD_1: case TYPE_MODEXACT_1_ODD: e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size, divisor); break; case TYPE_MOD_1C: case TYPE_MODEXACT_1C_ODD: e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size, divisor, carry); break; case TYPE_PREINV_MOD_1: e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size, divisor, refmpn_invert_limb (divisor)); break; case TYPE_MOD_34LSUB1: e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size); break; case TYPE_UDIV_QRNND: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p[1], e->s[0].p[0], divisor); break; case TYPE_SB_DIVREM_MN: refmpn_copyi (e->d[1].p, e->s[0].p, size); /* dividend */ refmpn_fill (e->d[0].p, size-size2, 0x98765432); /* quotient */ e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->d[1].p, size, e->s[1].p, size2); refmpn_zero (e->d[1].p+size2, size-size2); /* excess over remainder */ break; case TYPE_TDIV_QR: CALLING_CONVENTIONS (function) (e->d[0].p, e->d[1].p, 0, e->s[0].p, size, e->s[1].p, size2); break; case TYPE_GCD_1: /* Must have a non-zero src, but this probably isn't the best way to do it. */ if (refmpn_zero_p (e->s[0].p, size)) e->retval = 0; else e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size, divisor); break; case TYPE_GCD: /* Sources are destroyed, so they're saved and replaced, but a general approach to this might be better. Note that it's still e->s[0].p and e->s[1].p that are passed, to get the desired alignments. */ { mp_ptr s0 = refmpn_malloc_limbs (size); mp_ptr s1 = refmpn_malloc_limbs (size2); refmpn_copyi (s0, e->s[0].p, size); refmpn_copyi (s1, e->s[1].p, size2); mprotect_region (&s[0].region, PROT_READ|PROT_WRITE); mprotect_region (&s[1].region, PROT_READ|PROT_WRITE); e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, e->s[1].p, size2); refmpn_copyi (e->s[0].p, s0, size); refmpn_copyi (e->s[1].p, s1, size2); free (s0); free (s1); } break; case TYPE_GCD_FINDA: { /* FIXME: do this with a flag */ mp_limb_t c[2]; c[0] = e->s[0].p[0]; c[0] += (c[0] == 0); c[1] = e->s[0].p[0]; c[1] += (c[1] == 0); e->retval = CALLING_CONVENTIONS (function) (c); } break; case TYPE_MPZ_JACOBI: case TYPE_MPZ_KRONECKER: { mpz_t a, b; PTR(a) = e->s[0].p; SIZ(a) = ((carry&1)==0 ? size : -size); PTR(b) = e->s[1].p; SIZ(b) = ((carry&2)==0 ? size2 : -size2); e->retval = CALLING_CONVENTIONS (function) (a, b); } break; case TYPE_MPZ_KRONECKER_UI: { mpz_t a; PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size); e->retval = CALLING_CONVENTIONS(function) (a, (unsigned long)multiplier); } break; case TYPE_MPZ_KRONECKER_SI: { mpz_t a; PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size); e->retval = CALLING_CONVENTIONS (function) (a, (long) multiplier); } break; case TYPE_MPZ_UI_KRONECKER: { mpz_t b; PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size); e->retval = CALLING_CONVENTIONS(function) ((unsigned long)multiplier, b); } break; case TYPE_MPZ_SI_KRONECKER: { mpz_t b; PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size); e->retval = CALLING_CONVENTIONS (function) ((long) multiplier, b); } break; case TYPE_MUL_BASECASE: CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, e->s[1].p, size2); break; case TYPE_MUL_N: CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size); break; case TYPE_SQR: CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size); break; case TYPE_UMUL_PPMM: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p[0], e->s[0].p[1]); break; case TYPE_UMUL_PPMM_R: e->retval = CALLING_CONVENTIONS (function) (e->s[0].p[0], e->s[0].p[1], e->d[0].p); break; case TYPE_LSHIFT: case TYPE_RSHIFT: e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, shift); break; case TYPE_POPCOUNT: e->retval = (* (unsigned long (*)(ANYARGS)) CALLING_CONVENTIONS (function)) (e->s[0].p, size); break; case TYPE_HAMDIST: e->retval = (* (unsigned long (*)(ANYARGS)) CALLING_CONVENTIONS (function)) (e->s[0].p, e->s[1].p, size); break; case TYPE_SQRTREM: e->retval = (* (long (*)(ANYARGS)) CALLING_CONVENTIONS (function)) (e->d[0].p, e->d[1].p, e->s[0].p, size); break; case TYPE_ZERO: CALLING_CONVENTIONS (function) (e->d[0].p, size); break; case TYPE_GET_STR: { size_t sizeinbase, fill; char *dst; MPN_SIZEINBASE (sizeinbase, e->s[0].p, size, base); ASSERT_ALWAYS (sizeinbase <= d[0].size); fill = d[0].size - sizeinbase; if (d[0].high) { memset (e->d[0].p, 0xBA, fill); dst = (char *) e->d[0].p + fill; } else { dst = (char *) e->d[0].p; memset (dst + sizeinbase, 0xBA, fill); } if (POW2_P (base)) { e->retval = CALLING_CONVENTIONS (function) (dst, base, e->s[0].p, size); } else { refmpn_copy (e->d[1].p, e->s[0].p, size); e->retval = CALLING_CONVENTIONS (function) (dst, base, e->d[1].p, size); } refmpn_zero (e->d[1].p, size); /* cloberred or unused */ } break;#ifdef EXTRA_CALL EXTRA_CALL#endif default: printf ("Unknown routine type %d\n", choice->type); abort (); break; }}voidpointer_setup (struct each_t *e){ int i, j; for (i = 0; i < NUM_DESTS; i++) { switch (tr->dst_size[i]) { case 0: case SIZE_RETVAL: /* will be adjusted later */ d[i].size = size; break; case SIZE_1: d[i].size = 1; break; case SIZE_2: d[i].size = 2; break; case SIZE_3: d[i].size = 3; break; case SIZE_PLUS_1: d[i].size = size+1; break; case SIZE_SUM: if (tr->size2) d[i].size = size + size2; else d[i].size = 2*size; break; case SIZE_SIZE2: d[i].size = size2; break; case SIZE_DIFF: d[i].size = size - size2; break; case SIZE_DIFF_PLUS_1: d[i].size = size - size2 + 1; break; case SIZE_CEIL_HALF: d[i].size = (size+1)/2; break; case SIZE_GET_STR: { mp_limb_t ff = GMP_NUMB_MAX; MPN_SIZEINBASE (d[i].size, &ff - (size-1), size, base); } break; default: printf ("Unrecognised dst_size type %d\n", tr->dst_size[i]); abort (); } } /* establish e->d[].p destinations */ for (i = 0; i < NUM_DESTS; i++) { mp_size_t offset = 0; /* possible room for overlapping sources */ for (j = 0; j < numberof (overlap->s); j++) if (overlap->s[j] == i) offset = MAX (offset, s[j].align); if (d[i].high) { if (tr->dst_bytes[i]) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -