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:
parent
8bdb760606
commit
727385c4e1
@ -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 *);
|
||||
|
@ -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 */
|
||||
/* */
|
||||
|
Loading…
Reference in New Issue
Block a user