From 23d8d17b08857ddbfa8a4136493c8228c4e19eb3 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Thu, 17 Dec 2015 16:37:26 +0000 Subject: [PATCH] added stix_bitinvint() --- stix/kernel/Stix.st | 4 +- stix/kernel/test-005.st | 2 + stix/lib/bigint.c | 93 ++++++++++++++++++++++++++++++++++++++--- stix/lib/exec.c | 17 ++++++++ stix/lib/stix-prv.h | 5 +++ 5 files changed, 112 insertions(+), 9 deletions(-) diff --git a/stix/kernel/Stix.st b/stix/kernel/Stix.st index 3ecfd87..c6938d6 100644 --- a/stix/kernel/Stix.st +++ b/stix/kernel/Stix.st @@ -128,9 +128,7 @@ #method bitInvert { - ## - ##self primitiveFailed. - + ^-1 - self. } diff --git a/stix/kernel/test-005.st b/stix/kernel/test-005.st index ee7b745..5864365 100644 --- a/stix/kernel/test-005.st +++ b/stix/kernel/test-005.st @@ -352,6 +352,8 @@ PROCESS TESTING ((16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump. ((-16r1234 bitXor: -2r100000000000000000000000000000000000000000000000000000000000000000000000000000) printStringRadix: 16) dump. +((2r100000000000000000000000000000000000000000000000000000000000000000000000000000 bitInvert) printStringRadix: 16) dump. +((2r1111111 bitInvert) printStringRadix: 16) dump " FFI isNil dump. diff --git a/stix/lib/bigint.c b/stix/lib/bigint.c index 3da5689..e09be56 100644 --- a/stix/lib/bigint.c +++ b/stix/lib/bigint.c @@ -736,7 +736,6 @@ static void divide_unsigned_array ( static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y) { - stix_liw_t* a, * b; stix_oow_t as, bs, zs; stix_oop_t z; @@ -752,16 +751,22 @@ static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t if (as >= bs) { - a = ((stix_oop_liword_t)x)->slot; - b = ((stix_oop_liword_t)y)->slot; + add_unsigned_array ( + ((stix_oop_liword_t)x)->slot, as, + ((stix_oop_liword_t)y)->slot, bs, + ((stix_oop_liword_t)z)->slot + ); } else { - a = ((stix_oop_liword_t)y)->slot; - b = ((stix_oop_liword_t)x)->slot; + add_unsigned_array ( + ((stix_oop_liword_t)y)->slot, bs, + ((stix_oop_liword_t)x)->slot, as, + ((stix_oop_liword_t)z)->slot + ); } - add_unsigned_array (a, as, b, bs, ((stix_oop_liword_t)z)->slot); + return z; } @@ -2014,6 +2019,82 @@ oops_einval: return STIX_NULL; } +stix_oop_t stix_bitinvint (stix_t* stix, stix_oop_t x) +{ + if (STIX_OOP_IS_SMOOI(x)) + { + stix_ooi_t v; + + v = STIX_OOP_TO_SMOOI(x); + v = ~v; + + if (STIX_IN_SMOOI_RANGE(v)) return STIX_SMOOI_TO_OOP(v); + return make_bigint_with_ooi (stix, v); + } + else + { + stix_oop_t z; + stix_oow_t i, xs, zs, zalloc; + int negx; + + xs = STIX_OBJ_GET_SIZE(x); + negx = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? 1: 0; + + if (negx) + { + zalloc = xs; + zs = xs; + } + else + { + zalloc = xs + 1; + zs = xs; + } + + stix_pushtmp (stix, &x); + z = stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, zalloc); + stix_poptmp (stix); + if (!z) return STIX_NULL; + + if (negx) + { + stix_lidw_t w, carry; + + carry = 1; + for (i = 0; i < xs; i++) + { + w = (stix_lidw_t)(~((stix_oop_liword_t)x)->slot[i]) + carry; + carry = w >> STIX_LIW_BITS; + ((stix_oop_liword_t)z)->slot[i] = ~(stix_liw_t)w; + } + STIX_ASSERT (carry == 0); + } + else + { + stix_lidw_t w, carry; + + for (i = 0; i < xs; i++) + { + ((stix_oop_liword_t)z)->slot[i] = ~((stix_oop_liword_t)x)->slot[i]; + } + + /* 2's complement on the final result */ + ((stix_oop_liword_t)z)->slot[zs] = STIX_TYPE_MAX(stix_liw_t); + carry = 1; + for (i = 0; i <= zs; i++) + { + w = (stix_lidw_t)(~((stix_oop_liword_t)z)->slot[i]) + carry; + carry = w >> STIX_LIW_BITS; + ((stix_oop_liword_t)z)->slot[i] = (stix_liw_t)w; + } + STIX_ASSERT (carry == 0); + + STIX_OBJ_SET_CLASS (z, stix->_large_negative_integer); + } + + return normalize_bigint(stix, z); + } +} static stix_uint8_t ooch_val_tab[] = { diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 9754d10..9a70d4e 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -1240,6 +1240,22 @@ static int prim_integer_bitxor (stix_t* stix, stix_ooi_t nargs) return 1; } +static int prim_integer_bitinv (stix_t* stix, stix_ooi_t nargs) +{ + stix_oop_t rcv, res; + + STIX_ASSERT (nargs == 0); + + rcv = ACTIVE_STACK_GET(stix, stix->sp); + + res = stix_bitinvint (stix, rcv); + if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */ + + ACTIVE_STACK_POP (stix); + ACTIVE_STACK_SETTOP (stix, res); + return 1; +} + static int prim_integer_eq (stix_t* stix, stix_ooi_t nargs) { stix_oop_t rcv, arg; @@ -1785,6 +1801,7 @@ static prim_t primitives[] = { 1, prim_integer_bitand, "_integer_bitand" }, { 1, prim_integer_bitor, "_integer_bitor" }, { 1, prim_integer_bitxor, "_integer_bitxor" }, + { 0, prim_integer_bitinv, "_integer_bitinv" }, { 1, prim_integer_eq, "_integer_eq" }, { 1, prim_integer_ne, "_integer_ne" }, { 1, prim_integer_lt, "_integer_lt" }, diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 3a404a6..a674d70 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -1124,6 +1124,11 @@ stix_oop_t stix_bitxorints ( stix_oop_t y ); +stix_oop_t stix_bitinvint ( + stix_t* stix, + stix_oop_t x +); + stix_oop_t stix_strtoint ( stix_t* stix, const stix_ooch_t* str,