Skip to content

Remove CONFIG_INT128 checks from target/ppc/* #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: ferst-master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions include/qemu/int128.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,21 @@ static inline bool int128_ge(Int128 a, Int128 b)
return a >= b;
}

static inline bool int128_uge(Int128 a, Int128 b)
{
return ((__uint128_t)a) >= ((__uint128_t)b);
}

static inline bool int128_lt(Int128 a, Int128 b)
{
return a < b;
}

static inline bool int128_ult(Int128 a, Int128 b)
{
return (__uint128_t)a < (__uint128_t)b;
}

static inline bool int128_le(Int128 a, Int128 b)
{
return a <= b;
Expand Down Expand Up @@ -373,11 +383,21 @@ static inline bool int128_ge(Int128 a, Int128 b)
return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
}

static inline bool int128_uge(Int128 a, Int128 b)
{
return (uint64_t)a.hi > (uint64_t)b.hi || (a.hi == b.hi && a.lo >= b.lo);
}

static inline bool int128_lt(Int128 a, Int128 b)
{
return !int128_ge(a, b);
}

static inline bool int128_ult(Int128 a, Int128 b)
{
return !int128_uge(a, b);
}

static inline bool int128_le(Int128 a, Int128 b)
{
return int128_ge(b, a);
Expand Down
18 changes: 9 additions & 9 deletions target/ppc/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,14 @@ DEF_HELPER_FLAGS_5(vadduws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32)
DEF_HELPER_FLAGS_5(vsububs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32)
DEF_HELPER_FLAGS_5(vsubuhs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32)
DEF_HELPER_FLAGS_5(vsubuws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32)
DEF_HELPER_FLAGS_3(vadduqm, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_4(vaddecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_4(vaddeuqm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_3(vaddcuq, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(vsubuqm, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_4(vsubecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_4(vsubeuqm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_3(vsubcuq, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(VADDUQM, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_4(VADDECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_4(VADDEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_3(VADDCUQ, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(VSUBUQM, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_4(VSUBECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_4(VSUBEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr)
DEF_HELPER_FLAGS_3(VSUBCUQ, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_4(vsldoi, TCG_CALL_NO_RWG, void, avr, avr, avr, i32)
DEF_HELPER_FLAGS_3(vextractub, TCG_CALL_NO_RWG, void, avr, avr, i32)
DEF_HELPER_FLAGS_3(vextractuh, TCG_CALL_NO_RWG, void, avr, avr, i32)
Expand Down Expand Up @@ -310,7 +310,7 @@ DEF_HELPER_FLAGS_3(vbpermq, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(vpmsumb, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(vpmsumh, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(vpmsumw, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(vpmsumd, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_3(VPMSUMD, TCG_CALL_NO_RWG, void, avr, avr, avr)
DEF_HELPER_FLAGS_2(vextublx, TCG_CALL_NO_RWG, tl, tl, avr)
DEF_HELPER_FLAGS_2(vextuhlx, TCG_CALL_NO_RWG, tl, tl, avr)
DEF_HELPER_FLAGS_2(vextuwlx, TCG_CALL_NO_RWG, tl, tl, avr)
Expand Down
16 changes: 16 additions & 0 deletions target/ppc/insn32.decode
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ DSCLIQ 111111 ..... ..... ...... 001000010 . @Z22_tap_sh_rc
DSCRI 111011 ..... ..... ...... 001100010 . @Z22_ta_sh_rc
DSCRIQ 111111 ..... ..... ...... 001100010 . @Z22_tap_sh_rc

## Vector Exclusive-OR-based Instructions

VPMSUMD 000100 ..... ..... ..... 10011001000 @VX

## Vector Integer Instructions

VCMPEQUB 000100 ..... ..... ..... . 0000000110 @VC
Expand Down Expand Up @@ -546,6 +550,18 @@ VRLQNM 000100 ..... ..... ..... 00101000101 @VX

## Vector Integer Arithmetic Instructions

VADDCUQ 000100 ..... ..... ..... 00101000000 @VX
VADDUQM 000100 ..... ..... ..... 00100000000 @VX

VADDEUQM 000100 ..... ..... ..... ..... 111100 @VA
VADDECUQ 000100 ..... ..... ..... ..... 111101 @VA

VSUBCUQ 000100 ..... ..... ..... 10101000000 @VX
VSUBUQM 000100 ..... ..... ..... 10100000000 @VX

VSUBECUQ 000100 ..... ..... ..... ..... 111111 @VA
VSUBEUQM 000100 ..... ..... ..... ..... 111110 @VA

VEXTSB2W 000100 ..... 10000 ..... 11000000010 @VX_tb
VEXTSH2W 000100 ..... 10001 ..... 11000000010 @VX_tb
VEXTSB2D 000100 ..... 11000 ..... 11000000010 @VX_tb
Expand Down
229 changes: 39 additions & 190 deletions target/ppc/int_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1378,52 +1378,24 @@ PMSUM(vpmsumb, u8, u16, uint16_t)
PMSUM(vpmsumh, u16, u32, uint32_t)
PMSUM(vpmsumw, u32, u64, uint64_t)

void helper_vpmsumd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
void helper_VPMSUMD(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
{

#ifdef CONFIG_INT128
int i, j;
__uint128_t prod[2];

VECTOR_FOR_INORDER_I(i, u64) {
prod[i] = 0;
for (j = 0; j < 64; j++) {
if (a->u64[i] & (1ull << j)) {
prod[i] ^= (((__uint128_t)b->u64[i]) << j);
}
}
}

r->u128 = prod[0] ^ prod[1];

#else
int i, j;
ppc_avr_t prod[2];

VECTOR_FOR_INORDER_I(i, u64) {
prod[i].VsrD(1) = prod[i].VsrD(0) = 0;
for (j = 0; j < 64; j++) {
if (a->u64[i] & (1ull << j)) {
ppc_avr_t bshift;
if (j == 0) {
bshift.VsrD(0) = 0;
bshift.VsrD(1) = b->u64[i];
} else {
bshift.VsrD(0) = b->u64[i] >> (64 - j);
bshift.VsrD(1) = b->u64[i] << j;
}
prod[i].VsrD(1) ^= bshift.VsrD(1);
prod[i].VsrD(0) ^= bshift.VsrD(0);
Int128 tmp, prod[2] = {int128_zero(), int128_zero()};

for (j = 0; j < 64; j++) {
for (i = 0; i < ARRAY_SIZE(r->u64); i++) {
if (a->VsrD(i) & (1ull << j)) {
tmp = int128_make64(b->VsrD(i));
tmp = int128_lshift(tmp, j);
prod[i] = int128_xor(prod[i], tmp);
}
}
}

r->VsrD(1) = prod[0].VsrD(1) ^ prod[1].VsrD(1);
r->VsrD(0) = prod[0].VsrD(0) ^ prod[1].VsrD(0);
#endif
r->s128 = int128_xor(prod[0], prod[1]);
}


#if HOST_BIG_ENDIAN
#define PKBIG 1
#else
Expand Down Expand Up @@ -2098,189 +2070,66 @@ VGENERIC_DO(popcntd, u64)

#undef VGENERIC_DO

#if HOST_BIG_ENDIAN
#define QW_ONE { .u64 = { 0, 1 } }
#else
#define QW_ONE { .u64 = { 1, 0 } }
#endif

#ifndef CONFIG_INT128

static inline void avr_qw_not(ppc_avr_t *t, ppc_avr_t a)
{
t->u64[0] = ~a.u64[0];
t->u64[1] = ~a.u64[1];
}

static int avr_qw_cmpu(ppc_avr_t a, ppc_avr_t b)
{
if (a.VsrD(0) < b.VsrD(0)) {
return -1;
} else if (a.VsrD(0) > b.VsrD(0)) {
return 1;
} else if (a.VsrD(1) < b.VsrD(1)) {
return -1;
} else if (a.VsrD(1) > b.VsrD(1)) {
return 1;
} else {
return 0;
}
}

static void avr_qw_add(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b)
{
t->VsrD(1) = a.VsrD(1) + b.VsrD(1);
t->VsrD(0) = a.VsrD(0) + b.VsrD(0) +
(~a.VsrD(1) < b.VsrD(1));
}

static int avr_qw_addc(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b)
{
ppc_avr_t not_a;
t->VsrD(1) = a.VsrD(1) + b.VsrD(1);
t->VsrD(0) = a.VsrD(0) + b.VsrD(0) +
(~a.VsrD(1) < b.VsrD(1));
avr_qw_not(&not_a, a);
return avr_qw_cmpu(not_a, b) < 0;
}

#endif

void helper_vadduqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
void helper_VADDUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
{
#ifdef CONFIG_INT128
r->u128 = a->u128 + b->u128;
#else
avr_qw_add(r, *a, *b);
#endif
r->s128 = int128_add(a->s128, b->s128);
}

void helper_vaddeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
void helper_VADDEUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
{
#ifdef CONFIG_INT128
r->u128 = a->u128 + b->u128 + (c->u128 & 1);
#else

if (c->VsrD(1) & 1) {
ppc_avr_t tmp;

tmp.VsrD(0) = 0;
tmp.VsrD(1) = c->VsrD(1) & 1;
avr_qw_add(&tmp, *a, tmp);
avr_qw_add(r, tmp, *b);
} else {
avr_qw_add(r, *a, *b);
}
#endif
r->s128 = int128_add(int128_add(a->s128, b->s128),
int128_make64(int128_getlo(c->s128) & 1));
}

void helper_vaddcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
void helper_VADDCUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
{
#ifdef CONFIG_INT128
r->u128 = (~a->u128 < b->u128);
#else
ppc_avr_t not_a;

avr_qw_not(&not_a, *a);

r->VsrD(1) = int128_ult(int128_not(a->s128), b->s128);
r->VsrD(0) = 0;
r->VsrD(1) = (avr_qw_cmpu(not_a, *b) < 0);
#endif
}

void helper_vaddecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
void helper_VADDECUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
{
#ifdef CONFIG_INT128
int carry_out = (~a->u128 < b->u128);
if (!carry_out && (c->u128 & 1)) {
carry_out = ((a->u128 + b->u128 + 1) == 0) &&
((a->u128 != 0) || (b->u128 != 0));
}
r->u128 = carry_out;
#else

int carry_in = c->VsrD(1) & 1;
int carry_out = 0;
ppc_avr_t tmp;

carry_out = avr_qw_addc(&tmp, *a, *b);
bool carry_out = int128_ult(int128_not(a->s128), b->s128),
carry_in = int128_getlo(c->s128) & 1;

if (!carry_out && carry_in) {
ppc_avr_t one = QW_ONE;
carry_out = avr_qw_addc(&tmp, tmp, one);
carry_out = (int128_nz(a->s128) || int128_nz(b->s128)) &&
int128_eq(int128_add(a->s128, b->s128), int128_makes64(-1));
}

r->VsrD(0) = 0;
r->VsrD(1) = carry_out;
#endif
}

void helper_vsubuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
void helper_VSUBUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
{
#ifdef CONFIG_INT128
r->u128 = a->u128 - b->u128;
#else
ppc_avr_t tmp;
ppc_avr_t one = QW_ONE;

avr_qw_not(&tmp, *b);
avr_qw_add(&tmp, *a, tmp);
avr_qw_add(r, tmp, one);
#endif
r->s128 = int128_sub(a->s128, b->s128);
}

void helper_vsubeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
void helper_VSUBEUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
{
#ifdef CONFIG_INT128
r->u128 = a->u128 + ~b->u128 + (c->u128 & 1);
#else
ppc_avr_t tmp, sum;

avr_qw_not(&tmp, *b);
avr_qw_add(&sum, *a, tmp);

tmp.VsrD(0) = 0;
tmp.VsrD(1) = c->VsrD(1) & 1;
avr_qw_add(r, sum, tmp);
#endif
r->s128 = int128_add(int128_add(a->s128, int128_not(b->s128)),
int128_make64(int128_getlo(c->s128) & 1));
}

void helper_vsubcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
void helper_VSUBCUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
{
#ifdef CONFIG_INT128
r->u128 = (~a->u128 < ~b->u128) ||
(a->u128 + ~b->u128 == (__uint128_t)-1);
#else
int carry = (avr_qw_cmpu(*a, *b) > 0);
if (!carry) {
ppc_avr_t tmp;
avr_qw_not(&tmp, *b);
avr_qw_add(&tmp, *a, tmp);
carry = ((tmp.VsrSD(0) == -1ull) && (tmp.VsrSD(1) == -1ull));
}
Int128 tmp = int128_not(b->s128);

r->VsrD(1) = int128_ult(int128_not(a->s128), tmp) ||
int128_eq(int128_add(a->s128, tmp), int128_makes64(-1));
r->VsrD(0) = 0;
r->VsrD(1) = carry;
#endif
}

void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
void helper_VSUBECUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
{
#ifdef CONFIG_INT128
r->u128 =
(~a->u128 < ~b->u128) ||
((c->u128 & 1) && (a->u128 + ~b->u128 == (__uint128_t)-1));
#else
int carry_in = c->VsrD(1) & 1;
int carry_out = (avr_qw_cmpu(*a, *b) > 0);
if (!carry_out && carry_in) {
ppc_avr_t tmp;
avr_qw_not(&tmp, *b);
avr_qw_add(&tmp, *a, tmp);
carry_out = ((tmp.VsrD(0) == -1ull) && (tmp.VsrD(1) == -1ull));
}
Int128 tmp = int128_not(b->s128);
bool carry_out = int128_ult(int128_not(a->s128), tmp),
carry_in = int128_getlo(c->s128) & 1;

r->VsrD(1) = carry_out || (carry_in && int128_eq(int128_add(a->s128, tmp),
int128_makes64(-1)));
r->VsrD(0) = 0;
r->VsrD(1) = carry_out;
#endif
}

#define BCD_PLUS_PREF_1 0xC
Expand Down
Loading