Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
bigint bitwise and, or, xor
  • Loading branch information
moritz committed Nov 6, 2011
1 parent 4715e25 commit d78307d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/PAST/NQP.pir
Expand Up @@ -494,8 +494,11 @@ entry to produce the node to be returned.

# bitwise ops
maphash['bitor_i'] = 'bor__II'
maphash['bitor_I'] = 'nqp_bigint_bor__PPP'
maphash['bitxor_i'] = 'bxor__II'
maphash['bitxor_I'] = 'nqp_bigint_bxor__PPP'
maphash['bitand_i'] = 'band__II'
maphash['bitand_I'] = 'nqp_bigint_band__PPP'
maphash['bitneg_i'] = 'bnot__II'
maphash['bitshiftl_i'] = 'shl__III'
maphash['bitshiftl_I'] = 'nqp_bigint_shl__PPI'
Expand Down
22 changes: 22 additions & 0 deletions src/ops/nqp_bigint.ops
Expand Up @@ -178,3 +178,25 @@ inline op nqp_bigint_shl(out PMC, in PMC, in INT) :base_core {
b = get_bigint(interp, $1);
mp_mul_2d(a, $3, b);
}

inline op nqp_bigint_band(out PMC, in PMC, in PMC) :base_cor {
mp_int *a = get_bigint(interp, $2);
mp_int *b = get_bigint(interp, $3);
$1 = REPR($2)->allocate(interp, STABLE($2));
REPR($1)->initialize(interp, STABLE($1), OBJECT_BODY($1));
mp_and(a, b, get_bigint(interp, $1));
}
inline op nqp_bigint_bor(out PMC, in PMC, in PMC) :base_cor {
mp_int *a = get_bigint(interp, $2);
mp_int *b = get_bigint(interp, $3);
$1 = REPR($2)->allocate(interp, STABLE($2));
REPR($1)->initialize(interp, STABLE($1), OBJECT_BODY($1));
mp_or(a, b, get_bigint(interp, $1));
}
inline op nqp_bigint_bxor(out PMC, in PMC, in PMC) :base_cor {
mp_int *a = get_bigint(interp, $2);
mp_int *b = get_bigint(interp, $3);
$1 = REPR($2)->allocate(interp, STABLE($2));
REPR($1)->initialize(interp, STABLE($1), OBJECT_BODY($1));
mp_xor(a, b, get_bigint(interp, $1));
}
16 changes: 11 additions & 5 deletions t/nqp/60-bigint.t
@@ -1,5 +1,5 @@
#! nqp
plan(12);
#! nq5
plan(15);

pir::nqp_bigint_setup__v();

Expand All @@ -8,11 +8,12 @@ my $bi_type := $knowhow.new_type(:name('TestBigInt'), :repr('P6bigint'));
$bi_type.HOW.compose($bi_type);
sub s($x) { pir::nqp_bigint_to_str__SP($x) };
sub iseq($x, $y) { nqp::iseq_I($x, nqp::box_i($y, $bi_type)) }
sub box($x) { nqp::box_i($x, $bi_type) }

my $one := nqp::box_i(1, $bi_type);
my $one := box(1);

my $b := pir::nqp_bigint_from_str__PPS($one, '-123');
my $c := nqp::box_i(-123, $bi_type);
my $c := box(-123);

ok(s($b) eq '-123', 'can round-trip negative number (string)');
ok(s($c) eq '-123', 'can round-trip negative number (string) by boxing');
Expand All @@ -23,6 +24,11 @@ ok(iseq(nqp::mul_I($b, $b), 15129,), 'multiplication');
ok(iseq(nqp::add_I($b, $b), -246,), 'addition');
ok(nqp::iseq_I(nqp::sub_I($b, $b), nqp::box_i(0, $bi_type)), 'subtraction');
ok(nqp::iseq_I(nqp::div_I($b, $b), $one), 'division');

ok(iseq(nqp::bitshiftl_I($one, 3), 8), 'bitshift left');
ok(iseq($one, 1), 'original not modified by bitshift left');
ok(iseq(nqp::bitshiftr_I(nqp::box_i(16, $bi_type), 4), 1), 'bitshift right');
ok(iseq(nqp::bitshiftr_I(box(16), 4), 1), 'bitshift right');

ok(iseq(nqp::bitand_I(box(0xdead), box(0xbeef)), 0x9ead), 'bit and');
ok(iseq(nqp::bitor_I( box(0xdead), box(0xbeef)), 0xfeef), 'bit and');
ok(iseq(nqp::bitxor_I(box(0xdead), box(0xbeef)), 0x6042), 'bit and');

0 comments on commit d78307d

Please sign in to comment.