Skip to content

Commit

Permalink
Implement Num fallback case of pow_I.
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed Feb 8, 2014
1 parent 79c084e commit 1f165c8
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 34 deletions.
10 changes: 3 additions & 7 deletions src/core/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1807,15 +1807,11 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
cur_op += 8;
goto NEXT;
}
OP(pow_I): {
/* XXX Needs to handle the Num fallback case too. */
MVMObject * const type = GET_REG(cur_op, 8).o;
MVMObject * const result = MVM_repr_alloc_init(tc, type);
MVM_bigint_pow(tc, result, GET_REG(cur_op, 2).o, GET_REG(cur_op, 4).o);
GET_REG(cur_op, 0).o = result;
OP(pow_I):
GET_REG(cur_op, 0).o = MVM_bigint_pow(tc, GET_REG(cur_op, 2).o,
GET_REG(cur_op, 4).o, GET_REG(cur_op, 6).o, GET_REG(cur_op, 8).o);
cur_op += 10;
goto NEXT;
}
OP(cmp_I): {
MVMObject *a = GET_REG(cur_op, 2).o, *b = GET_REG(cur_op, 4).o;
GET_REG(cur_op, 0).i64 = MVM_bigint_cmp(tc, a, b);
Expand Down
53 changes: 27 additions & 26 deletions src/math/bigintops.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,52 +469,53 @@ void MVM_bigint_div(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMOb
}
}

void MVM_bigint_pow(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMObject *b) {
MVMObject * MVM_bigint_pow(MVMThreadContext *tc, MVMObject *a, MVMObject *b,
MVMObject *num_type, MVMObject *int_type) {
MVMP6bigintBody *ba = get_bigint_body(tc, a);
MVMP6bigintBody *bb = get_bigint_body(tc, b);
MVMP6bigintBody *bc = get_bigint_body(tc, result);
MVMObject *r = NULL;

mp_int *tmp[2] = { NULL, NULL };
mp_int *base = force_bigint(ba, tmp);
mp_int *exponent = force_bigint(bb, tmp);
mp_int *ic = malloc(sizeof(mp_int));
mp_digit exponent_d = 0;
int cmp = mp_cmp_d(exponent, 0);
mp_init(ic);

if ((cmp == MP_EQ) || (MP_EQ == mp_cmp_d(base, 1))) {
mp_set_int(ic, 1);
r = MVM_repr_box_int(tc, int_type, 1);
}
else {
if (cmp == MP_GT) {
exponent_d = mp_get_int(exponent);
if ((MP_GT == mp_cmp_d(exponent, exponent_d))) {
cmp = mp_cmp_d(base, 0);
if ((MP_EQ == cmp) || (MP_EQ == mp_cmp_d(base, 1))) {
mp_copy(base, ic);
else if (cmp == MP_GT) {
mp_int *ic = malloc(sizeof(mp_int));
mp_init(ic);
exponent_d = mp_get_int(exponent);
if ((MP_GT == mp_cmp_d(exponent, exponent_d))) {
cmp = mp_cmp_d(base, 0);
if ((MP_EQ == cmp) || (MP_EQ == mp_cmp_d(base, 1))) {
mp_copy(base, ic);
}
else {
MVMnum64 ZERO = 0.0;
if (MP_GT == cmp) {
mp_set_int(ic, (MVMnum64)1.0 / ZERO);
}
else {
MVMnum64 ZERO = 0.0;
if (MP_GT == cmp) {
mp_set_int(ic, (MVMnum64)1.0 / ZERO);
}
else {
mp_set_int(ic, (MVMnum64)(-1.0) / ZERO);
}
mp_set_int(ic, (MVMnum64)(-1.0) / ZERO);
}
}
else {
mp_expt_d(base, exponent_d, ic);
}
}
else {
MVMnum64 f_base = mp_get_double(base);
MVMnum64 f_exp = mp_get_double(exponent);
mp_set_int(ic, pow(f_base, f_exp));
mp_expt_d(base, exponent_d, ic);
}
r = MVM_repr_alloc_init(tc, int_type);
store_bigint_result(get_bigint_body(tc, r), ic);
}
else {
MVMnum64 f_base = mp_get_double(base);
MVMnum64 f_exp = mp_get_double(exponent);
r = MVM_repr_box_num(tc, num_type, pow(f_base, f_exp));
}
store_bigint_result(bc, ic);
clear_temp_bigints(tmp, 2);
return r;
}

void MVM_bigint_shl(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMint64 n) {
Expand Down
3 changes: 2 additions & 1 deletion src/math/bigintops.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ void MVM_bigint_sub(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMOb
void MVM_bigint_mul(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMObject *b);
void MVM_bigint_div(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMObject *b);
void MVM_bigint_mod(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMObject *b);
void MVM_bigint_pow(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMObject *b);
MVMObject * MVM_bigint_pow(MVMThreadContext *tc, MVMObject *a, MVMObject *b,
MVMObject *num_type, MVMObject *int_type);
void MVM_bigint_gcd(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMObject *b);
void MVM_bigint_lcm(MVMThreadContext *tc, MVMObject *result, MVMObject *a, MVMObject *b);

Expand Down

0 comments on commit 1f165c8

Please sign in to comment.