libdecnumber: introduce decNumberFrom[U]Int128

This will be used to implement PowerPC's dcffixqq.

Signed-off-by: Luis Pires <luis.pires@eldorado.org.br>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20211029192417.400707-2-luis.pires@eldorado.org.br>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Luis Pires 2021-10-29 16:24:03 -03:00 committed by David Gibson
parent 8bdb760606
commit 727385c4e1
2 changed files with 38 additions and 0 deletions

View file

@ -116,6 +116,8 @@
decNumber * decNumberFromUInt32(decNumber *, uint32_t);
decNumber *decNumberFromInt64(decNumber *, int64_t);
decNumber *decNumberFromUInt64(decNumber *, uint64_t);
decNumber *decNumberFromInt128(decNumber *, uint64_t, int64_t);
decNumber *decNumberFromUInt128(decNumber *, uint64_t, uint64_t);
decNumber * decNumberFromString(decNumber *, const char *, decContext *);
char * decNumberToString(const decNumber *, char *);
char * decNumberToEngString(const decNumber *, char *);

View file

@ -167,6 +167,7 @@
/* ------------------------------------------------------------------ */
#include "qemu/osdep.h"
#include "qemu/host-utils.h"
#include "libdecnumber/dconfig.h"
#include "libdecnumber/decNumber.h"
#include "libdecnumber/decNumberLocal.h"
@ -462,6 +463,41 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
return dn;
} /* decNumberFromUInt64 */
decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
{
uint64_t unsig_hi = hi;
if (hi < 0) {
if (lo == 0) {
unsig_hi = -unsig_hi;
} else {
unsig_hi = ~unsig_hi;
lo = -lo;
}
}
decNumberFromUInt128(dn, lo, unsig_hi);
if (hi < 0) {
dn->bits = DECNEG; /* sign needed */
}
return dn;
} /* decNumberFromInt128 */
decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
{
uint64_t rem;
Unit *up; /* work pointer */
decNumberZero(dn); /* clean */
if (lo == 0 && hi == 0) {
return dn; /* [or decGetDigits bad call] */
}
for (up = dn->lsu; hi > 0 || lo > 0; up++) {
rem = divu128(&lo, &hi, DECDPUNMAX + 1);
*up = (Unit)rem;
}
dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
return dn;
} /* decNumberFromUInt128 */
/* ------------------------------------------------------------------ */
/* to-int64 -- conversion to int64 */
/* */