Ejemplo n.º 1
0
Archivo: main.cpp Proyecto: CCJY/coliru
// Computes aR * bR mod N with R = 2**64.
inline uint64_t montmul64(uint64_t a, uint64_t b, uint64_t N, uint64_t Nneginv) {
    std::pair<uint64_t, uint64_t> T, mN;
    
    uint64_t Th, Tl, m, mNh, mNl, th;

    std::tie(Th, Tl) = mulu64(a, b);
    m = Tl * Nneginv;
    std::tie(mNh, mNl) = mulu64(m, N);

    bool lc = Tl + mNl < Tl;
    th = Th + mNh + lc;
    bool hc = (th < Th) || (th == Th && lc);

    if (hc > 0 || th >= N) th = th - N;

    return th;
}
Ejemplo n.º 2
0
static void test_u(void)
{
    int i;

    for (i = 0; i < ARRAY_SIZE(test_u_data); ++i) {
        uint64_t rl, rh;
        mulu64(&rl, &rh, test_u_data[i].a, test_u_data[i].b);
        g_assert_cmpuint(rl, ==, test_u_data[i].rl);
        g_assert_cmpuint(rh, ==, test_u_data[i].rh);
    }
}
Ejemplo n.º 3
0
uint64_t HELPER(muluh_i64)(uint64_t arg1, uint64_t arg2)
{
    uint64_t l, h;
    mulu64(&l, &h, arg1, arg2);
    return h;
}
Ejemplo n.º 4
0
static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
{
    uint64_t l64, h64;

    switch (op) {
    CASE_OP_32_64(add):
        return x + y;

    CASE_OP_32_64(sub):
        return x - y;

    CASE_OP_32_64(mul):
        return x * y;

    CASE_OP_32_64(and):
        return x & y;

    CASE_OP_32_64(or):
        return x | y;

    CASE_OP_32_64(xor):
        return x ^ y;

    case INDEX_op_shl_i32:
        return (uint32_t)x << (y & 31);

    case INDEX_op_shl_i64:
        return (uint64_t)x << (y & 63);

    case INDEX_op_shr_i32:
        return (uint32_t)x >> (y & 31);

    case INDEX_op_trunc_shr_i32:
    case INDEX_op_shr_i64:
        return (uint64_t)x >> (y & 63);

    case INDEX_op_sar_i32:
        return (int32_t)x >> (y & 31);

    case INDEX_op_sar_i64:
        return (int64_t)x >> (y & 63);

    case INDEX_op_rotr_i32:
        return ror32(x, y & 31);

    case INDEX_op_rotr_i64:
        return (TCGArg)ror64(x, y & 63);

    case INDEX_op_rotl_i32:
        return rol32(x, y & 31);

    case INDEX_op_rotl_i64:
        return (TCGArg)rol64(x, y & 63);

    CASE_OP_32_64(not):
        return ~x;

    CASE_OP_32_64(neg):
        return 0-x;

    CASE_OP_32_64(andc):
        return x & ~y;

    CASE_OP_32_64(orc):
        return x | ~y;

    CASE_OP_32_64(eqv):
        return ~(x ^ y);

    CASE_OP_32_64(nand):
        return ~(x & y);

    CASE_OP_32_64(nor):
        return ~(x | y);

    CASE_OP_32_64(ext8s):
        return (int8_t)x;

    CASE_OP_32_64(ext16s):
        return (int16_t)x;

    CASE_OP_32_64(ext8u):
        return (uint8_t)x;

    CASE_OP_32_64(ext16u):
        return (uint16_t)x;

    case INDEX_op_ext32s_i64:
        return (int32_t)x;

    case INDEX_op_ext32u_i64:
        return (uint32_t)x;

    case INDEX_op_muluh_i32:
        return ((uint64_t)(uint32_t)x * (uint32_t)y) >> 32;
    case INDEX_op_mulsh_i32:
        return ((int64_t)(int32_t)x * (int32_t)y) >> 32;

    case INDEX_op_muluh_i64:
        mulu64(&l64, &h64, x, y);
        return (TCGArg)h64;
    case INDEX_op_mulsh_i64:
        muls64(&l64, &h64, x, y);
        return (TCGArg)h64;

    case INDEX_op_div_i32:
        /* Avoid crashing on divide by zero, otherwise undefined.  */
        return (int32_t)x / ((int32_t)y ? (int32_t)y : 1);
    case INDEX_op_divu_i32:
        return (uint32_t)x / ((uint32_t)y ? (uint32_t)y : 1);
    case INDEX_op_div_i64:
        return (int64_t)x / ((int64_t)y ? (int64_t)y : 1);
    case INDEX_op_divu_i64:
        return (uint64_t)x / ((uint64_t)y ? (uint64_t)y : 1);

    case INDEX_op_rem_i32:
        return (int32_t)x % ((int32_t)y ? (int32_t)y : 1);
    case INDEX_op_remu_i32:
        return (uint32_t)x % ((uint32_t)y ? (uint32_t)y : 1);
    case INDEX_op_rem_i64:
        return (int64_t)x % ((int64_t)y ? (int64_t)y : 1);
    case INDEX_op_remu_i64:
        return (uint64_t)x % ((uint64_t)y ? (uint64_t)y : 1);

    default:
        fprintf(stderr,
                "Unrecognized operation %d in do_constant_folding.\n", op);
        tcg_abort();
    }
}