Skip to content

Commit

Permalink
factored out duplicate code blocks from zadd/zsub
Browse files Browse the repository at this point in the history
  • Loading branch information
suiginsoft committed Nov 14, 2018
1 parent 1bba62e commit cecedd0
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 183 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ DEPS := \
hebimath.h \
config.h \
internal.h \
src/z/zaddsub.h \
src/z/zaddsubu.h \
src/p/pcommon.h \
$(DEPS_$(DRIVER_selected))

Expand Down
54 changes: 3 additions & 51 deletions src/z/zadd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,14 @@
* See LICENSE file for copyright and license details
*/

#include "../../internal.h"
#include "zaddsub.h"

HEBI_API
void
hebi_zadd(hebi_zptr r, hebi_zsrcptr a, hebi_zsrcptr b)
{
hebi_packet *rp;
uint64_t carry;
size_t au;
size_t bu;
int as;
int bs;
int c;

if (UNLIKELY(!(as = a->hz_sign))) {
hebi_zset(r, b);
Expand All @@ -26,49 +21,6 @@ hebi_zadd(hebi_zptr r, hebi_zsrcptr a, hebi_zsrcptr b)
hebi_zset(r, a);
return;
}

au = a->hz_used;
bu = b->hz_used;
if (au < bu || (au == bu && r == b)) {
SWAP(hebi_zsrcptr, a, b);
SWAP(size_t, au, bu);
SWAP(int, as, bs);
}

if (SIGNXOR(as, bs) >= 0) {
if (r == a) {
rp = hebi_zgrowcopy__(r, au + 1);
carry = hebi_padda(rp, b->hz_packs, au, bu);
} else {
rp = hebi_zgrowcopyif__(r, au + 1, r == b);
carry = hebi_padd(rp, a->hz_packs, b->hz_packs, au, bu);
}
if (carry != 0) {
hebi_psetu(rp + au, carry);
au++;
}
} else {
if (au == bu) {
c = hebi_pcmp(a->hz_packs, b->hz_packs, au);
if (UNLIKELY(!c)) {
hebi_zsetzero(r);
return;
}
if (c < 0) {
SWAP(hebi_zsrcptr, a, b);
as = -as;
}
}
if (r == a) {
rp = r->hz_packs;
(void)hebi_psuba(rp, b->hz_packs, au, bu);
} else {
rp = hebi_zgrowcopyif__(r, au, r == b);
(void)hebi_psub(rp, a->hz_packs, b->hz_packs, au, bu);
}
au = hebi_pnorm(rp, au);
}

r->hz_used = au;
r->hz_sign = as;

hebi_zaddsub__(r, a, b, as, bs);
}
63 changes: 63 additions & 0 deletions src/z/zaddsub.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* hebimath - arbitrary precision arithmetic library
* See LICENSE file for copyright and license details
*/

#include "../../internal.h"

static inline HEBI_ALWAYSINLINE
void
hebi_zaddsub__(hebi_zptr r, hebi_zsrcptr a, hebi_zsrcptr b, int as, int bs)
{
hebi_packet *rp;
uint64_t carry;
size_t au;
size_t bu;
int c;

au = a->hz_used;
bu = b->hz_used;

if ((au < bu) || ((au == bu) && (r == b))) {
SWAP(hebi_zsrcptr, a, b);
SWAP(size_t, au, bu);
SWAP(int, as, bs);
}

if (SIGNXOR(as, bs) >= 0) {
if (r == a) {
rp = hebi_zgrowcopy__(r, au + 1);
carry = hebi_padda(rp, b->hz_packs, au, bu);
} else {
rp = hebi_zgrowcopyif__(r, au + 1, r == b);
carry = hebi_padd(rp, a->hz_packs, b->hz_packs, au, bu);
}
if (carry != 0) {
hebi_psetu(rp + au, carry);
au++;
}
} else {
if (au == bu) {
c = hebi_pcmp(a->hz_packs, b->hz_packs, au);
if (UNLIKELY(!c)) {
hebi_zsetzero(r);
return;
}
if (c < 0) {
SWAP(hebi_zsrcptr, a, b);
as = -as;
}
}
if (r == a) {
rp = r->hz_packs;
(void)hebi_psuba(rp, b->hz_packs, au, bu);
} else {
rp = hebi_zgrowcopyif__(r, au, r == b);
(void)hebi_psub(rp, a->hz_packs, b->hz_packs, au, bu);
}
au = hebi_pnorm(rp, au);
}

r->hz_used = au;
r->hz_sign = as;
}
50 changes: 50 additions & 0 deletions src/z/zaddsubu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* hebimath - arbitrary precision arithmetic library
* See LICENSE file for copyright and license details
*/

#include "../../internal.h"

static inline HEBI_ALWAYSINLINE
void
hebi_zaddsubu__(hebi_zptr r, hebi_zsrcptr a, uint64_t b, int as, int bs)
{
const hebi_packet *ap;
hebi_packet *rp;
uint64_t c;
size_t u;

u = a->hz_used;

if (((as > 0) && (bs > 0)) || ((as < 0) && (bs < 0))) {
rp = hebi_zgrowcopyif__(r, u + 1, r == a);
ap = a->hz_packs;
if ((c = hebi_paddu(rp, ap, b, u)) != 0) {
hebi_psetu(rp + u, c);
u++;
}
r->hz_used = u;
r->hz_sign = as;
return;
}

ap = a->hz_packs;

if ((u > 1) || (ap->hp_limbs64[0] > b) || (ap->hp_limbs64[1] != 0)) {
rp = r == a ? r->hz_packs : hebi_zgrow__(r, u);
(void)hebi_psubu(rp, ap, b, u);
u = hebi_pnorm(rp, u);
r->hz_used = u;
r->hz_sign = as;
} else {
c = b - ap->hp_limbs64[0];
if (LIKELY(c)) {
rp = hebi_zgrow__(r, 1);
hebi_psetu(rp, c);
r->hz_used = 1;
r->hz_sign = bs;
} else {
r->hz_sign = 0;
}
}
}
45 changes: 4 additions & 41 deletions src/z/zaddu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,23 @@
* See LICENSE file for copyright and license details
*/

#include "../../internal.h"
#include "zaddsubu.h"

HEBI_API
void
hebi_zaddu(hebi_zptr r, hebi_zsrcptr a, uint64_t b)
{
const hebi_packet *ap;
hebi_packet *rp;
uint64_t c;
size_t u;
int s;
int as;

if (UNLIKELY(!b)) {
hebi_zset(r, a);
return;
}

if (UNLIKELY(!(s = a->hz_sign))) {
if (UNLIKELY(!(as = a->hz_sign))) {
hebi_zsetu(r, b);
return;
}

u = a->hz_used;

if (s > 0) {
rp = hebi_zgrowcopyif__(r, u + 1, r == a);
ap = a->hz_packs;
if ((c = hebi_paddu(rp, ap, b, u)))
hebi_psetu(rp + u++, c);
r->hz_used = u;
r->hz_sign = s;
return;
}

ap = a->hz_packs;

if (u > 1 || ap->hp_limbs64[0] > b || ap->hp_limbs64[1] != 0) {
if (r == a)
rp = r->hz_packs;
else
rp = hebi_zgrow__(r, u);
(void)hebi_psubu(rp, ap, b, u);
u = hebi_pnorm(rp, u);
r->hz_used = u;
r->hz_sign = s;
} else {
c = b - ap->hp_limbs64[0];
if (LIKELY(c)) {
rp = hebi_zgrow__(r, 1);
hebi_psetu(rp, c);
r->hz_used = 1;
r->hz_sign = 1;
} else {
r->hz_sign = 0;
}
}
hebi_zaddsubu__(r, a, b, as, 1);
}
52 changes: 2 additions & 50 deletions src/z/zsub.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,14 @@
* See LICENSE file for copyright and license details
*/

#include "../../internal.h"
#include "zaddsub.h"

HEBI_API
void
hebi_zsub(hebi_zptr r, hebi_zsrcptr a, hebi_zsrcptr b)
{
hebi_packet *rp;
uint64_t carry;
size_t au;
size_t bu;
int as;
int bs;
int c;

if (UNLIKELY(!(as = a->hz_sign))) {
hebi_zset(r, b);
Expand All @@ -28,48 +23,5 @@ hebi_zsub(hebi_zptr r, hebi_zsrcptr a, hebi_zsrcptr b)
return;
}

au = a->hz_used;
bu = b->hz_used;
if ((au < bu) || ((au == bu) && (r == b))) {
SWAP(hebi_zsrcptr, a, b);
SWAP(size_t, au, bu);
SWAP(int, as, bs);
}

if (SIGNXOR(as, bs) >= 0) {
if (r == a) {
rp = hebi_zgrowcopy__(r, au + 1);
carry = hebi_padda(rp, b->hz_packs, au, bu);
} else {
rp = hebi_zgrowcopyif__(r, au + 1, r == b);
carry = hebi_padd(rp, a->hz_packs, b->hz_packs, au, bu);
}
if (carry != 0) {
hebi_psetu(rp + au, carry);
au++;
}
} else {
if (au == bu) {
c = hebi_pcmp(a->hz_packs, b->hz_packs, au);
if (UNLIKELY(!c)) {
hebi_zsetzero(r);
return;
}
if (c < 0) {
SWAP(hebi_zsrcptr, a, b);
as = -as;
}
}
if (r == a) {
rp = r->hz_packs;
(void)hebi_psuba(rp, b->hz_packs, au, bu);
} else {
rp = hebi_zgrowcopyif__(r, au, r == b);
(void)hebi_psub(rp, a->hz_packs, b->hz_packs, au, bu);
}
au = hebi_pnorm(rp, au);
}

r->hz_used = au;
r->hz_sign = as;
hebi_zaddsub__(r, a, b, as, bs);
}
45 changes: 4 additions & 41 deletions src/z/zsubu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,24 @@
* See LICENSE file for copyright and license details
*/

#include "../../internal.h"
#include "zaddsubu.h"

HEBI_API
void
hebi_zsubu(hebi_zptr r, hebi_zsrcptr a, uint64_t b)
{
const hebi_packet *ap;
hebi_packet *rp;
uint64_t c;
size_t u;
int s;
int as;

if (UNLIKELY(!b)) {
hebi_zset(r, a);
return;
}

if (UNLIKELY(!(s = a->hz_sign))) {
if (UNLIKELY(!(as = a->hz_sign))) {
hebi_zsetu(r, b);
hebi_zneg(r, r);
return;
}

u = a->hz_used;

if (s < 0) {
rp = hebi_zgrowcopyif__(r, u + 1, r == a);
ap = a->hz_packs;
if ((c = hebi_paddu(rp, ap, b, u)))
hebi_psetu(rp + u++, c);
r->hz_used = u;
r->hz_sign = s;
return;
}

ap = a->hz_packs;

if (u > 1 || ap->hp_limbs64[0] > b || ap->hp_limbs64[1] != 0) {
if (r == a)
rp = r->hz_packs;
else
rp = hebi_zgrow__(r, u);
(void)hebi_psubu(rp, ap, b, u);
u = hebi_pnorm(rp, u);
r->hz_used = u;
r->hz_sign = s;
} else {
c = b - ap->hp_limbs64[0];
if (LIKELY(c)) {
rp = hebi_zgrow__(r, 1);
hebi_psetu(rp, c);
r->hz_used = 1;
r->hz_sign = -1;
} else {
r->hz_sign = 0;
}
}
hebi_zaddsubu__(r, a, b, as, -1);
}

0 comments on commit cecedd0

Please sign in to comment.