Skip to content

target/ppc: Move {v,xx}sel and {v,xx}perm to decodetree, implement xxpermx #36

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

Closed
wants to merge 11 commits into from
Closed
21 changes: 0 additions & 21 deletions target/ppc/fpu_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -2987,27 +2987,6 @@ uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb)
return xt;
}

#define VSX_XXPERM(op, indexed) \
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
ppc_vsr_t *xa, ppc_vsr_t *pcv) \
{ \
ppc_vsr_t t = *xt; \
int i, idx; \
\
for (i = 0; i < 16; i++) { \
idx = pcv->VsrB(i) & 0x1F; \
if (indexed) { \
idx = 31 - idx; \
} \
t.VsrB(i) = (idx <= 15) ? xa->VsrB(idx) \
: xt->VsrB(idx - 16); \
} \
*xt = t; \
}

VSX_XXPERM(xxperm, 0)
VSX_XXPERM(xxpermr, 1)

void helper_xvxsigsp(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)
{
ppc_vsr_t t = { };
Expand Down
8 changes: 3 additions & 5 deletions target/ppc/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,8 @@ DEF_HELPER_2(vupklsh, void, avr, avr)
DEF_HELPER_2(vupklsw, void, avr, avr)
DEF_HELPER_5(vmsumubm, void, env, avr, avr, avr, avr)
DEF_HELPER_5(vmsummbm, void, env, avr, avr, avr, avr)
DEF_HELPER_5(vsel, void, env, avr, avr, avr, avr)
DEF_HELPER_5(vperm, void, env, avr, avr, avr, avr)
DEF_HELPER_5(vpermr, void, env, avr, avr, avr, avr)
DEF_HELPER_4(VPERM, void, avr, avr, avr, avr)
DEF_HELPER_4(VPERMR, void, avr, avr, avr, avr)
DEF_HELPER_4(vpkshss, void, env, avr, avr, avr)
DEF_HELPER_4(vpkshus, void, env, avr, avr, avr)
DEF_HELPER_4(vpkswss, void, env, avr, avr, avr)
Expand Down Expand Up @@ -517,9 +516,8 @@ DEF_HELPER_3(xvrspic, void, env, vsr, vsr)
DEF_HELPER_3(xvrspim, void, env, vsr, vsr)
DEF_HELPER_3(xvrspip, void, env, vsr, vsr)
DEF_HELPER_3(xvrspiz, void, env, vsr, vsr)
DEF_HELPER_4(xxperm, void, env, vsr, vsr, vsr)
DEF_HELPER_4(xxpermr, void, env, vsr, vsr, vsr)
DEF_HELPER_4(xxextractuw, void, env, vsr, vsr, i32)
DEF_HELPER_5(XXPERMX, void, vsr, vsr, vsr, vsr, tl)
DEF_HELPER_4(xxinsertw, void, env, vsr, vsr, i32)
DEF_HELPER_3(xvxsigsp, void, env, vsr, vsr)
DEF_HELPER_5(XXBLENDVB, void, vsr, vsr, vsr, vsr, i32)
Expand Down
30 changes: 27 additions & 3 deletions target/ppc/insn32.decode
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,21 @@
&X_vrt_frbp vrt frbp
@X_vrt_frbp ...... vrt:5 ..... ....0 .......... . &X_vrt_frbp frbp=%x_frbp

%xx_xt 0:1 21:5
%xx_xb 1:1 11:5
%xx_xa 2:1 16:5
%xx_xc 3:1 6:5
&XX2 xt xb uim:uint8_t
%xx2_xt 0:1 21:5
%xx2_xb 1:1 11:5
@XX2 ...... ..... ... uim:2 ..... ......... .. &XX2 xt=%xx2_xt xb=%xx2_xb
@XX2 ...... ..... ... uim:2 ..... ......... .. &XX2 xt=%xx_xt xb=%xx_xb

&XX3 xt xa xb
@XX3 ...... ..... ..... ..... ........ ... &XX3 xt=%xx_xt xa=%xx_xa xb=%xx_xb

&XX3_dm xt xa xb dm
@XX3_dm ...... ..... ..... ..... . dm:2 ..... ... &XX3_dm xt=%xx_xt xa=%xx_xa xb=%xx_xb

&XX4 xt xa xb xc
@XX4 ...... ..... ..... ..... ..... .. .... &XX4 xt=%xx_xt xa=%xx_xa xb=%xx_xb xc=%xx_xc

&Z22_bf_fra bf fra dm
@Z22_bf_fra ...... bf:3 .. fra:5 dm:6 ......... . &Z22_bf_fra
Expand Down Expand Up @@ -408,6 +419,11 @@ VINSWVRX 000100 ..... ..... ..... 00110001111 @VX
VSLDBI 000100 ..... ..... ..... 00 ... 010110 @VN
VSRDBI 000100 ..... ..... ..... 01 ... 010110 @VN

VPERM 000100 ..... ..... ..... ..... 101011 @VA
VPERMR 000100 ..... ..... ..... ..... 111011 @VA

VSEL 000100 ..... ..... ..... ..... 101010 @VA

# VSX Load/Store Instructions

LXV 111101 ..... ..... ............ . 001 @DQ_TSX
Expand All @@ -424,6 +440,14 @@ STXVPX 011111 ..... ..... ..... 0111001101 - @X_TSXP
XXSPLTIB 111100 ..... 00 ........ 0101101000 . @X_imm8
XXSPLTW 111100 ..... ---.. ..... 010100100 . . @XX2

## VSX Permute Instructions

XXPERM 111100 ..... ..... ..... 00011010 ... @XX3
XXPERMR 111100 ..... ..... ..... 00111010 ... @XX3
XXPERMDI 111100 ..... ..... ..... 0 .. 01010 ... @XX3_dm

XXSEL 111100 ..... ..... ..... ..... 11 .... @XX4

## VSX Vector Load Special Value Instruction

LXVKQ 111100 ..... 11111 ..... 0101101000 . @X_uim5
32 changes: 20 additions & 12 deletions target/ppc/insn64.decode
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,20 @@
...... ..... .... . ................ \
&8RR_D si=%8rr_si xt=%8rr_xt

# Format XX4
&XX4 xt xa xb xc
%xx4_xt 0:1 21:5
%xx4_xa 2:1 16:5
%xx4_xb 1:1 11:5
%xx4_xc 3:1 6:5
@XX4 ........ ........ ........ ........ \
# Format 8RR:XX4
%8rr_xx_xt 0:1 21:5
%8rr_xx_xa 2:1 16:5
%8rr_xx_xb 1:1 11:5
%8rr_xx_xc 3:1 6:5
&8RR_XX4 xt xa xb xc
@8RR_XX4 ........ ........ ........ ........ \
...... ..... ..... ..... ..... .. .... \
&XX4 xt=%xx4_xt xa=%xx4_xa xb=%xx4_xb xc=%xx4_xc
&8RR_XX4 xt=%8rr_xx_xt xa=%8rr_xx_xa xb=%8rr_xx_xb xc=%8rr_xx_xc

&8RR_XX4_uim3 xt xa xb xc uim3
@8RR_XX4_uim3 ...... .. .... .. ............... uim3:3 \
...... ..... ..... ..... ..... .. .... \
&8RR_XX4_uim3 xt=%8rr_xx_xt xa=%8rr_xx_xa xb=%8rr_xx_xb xc=%8rr_xx_xc

### Fixed-Point Load Instructions

Expand Down Expand Up @@ -187,10 +192,13 @@ XXSPLTI32DX 000001 01 0000 -- -- ................ \
100000 ..... 000 .. ................ @8RR_D_IX

XXBLENDVD 000001 01 0000 -- ------------------ \
100001 ..... ..... ..... ..... 11 .... @XX4
100001 ..... ..... ..... ..... 11 .... @8RR_XX4
XXBLENDVW 000001 01 0000 -- ------------------ \
100001 ..... ..... ..... ..... 10 .... @XX4
100001 ..... ..... ..... ..... 10 .... @8RR_XX4
XXBLENDVH 000001 01 0000 -- ------------------ \
100001 ..... ..... ..... ..... 01 .... @XX4
100001 ..... ..... ..... ..... 01 .... @8RR_XX4
XXBLENDVB 000001 01 0000 -- ------------------ \
100001 ..... ..... ..... ..... 00 .... @XX4
100001 ..... ..... ..... ..... 00 .... @8RR_XX4

XXPERMX 000001 01 0000 -- --------------- ... \
100010 ..... ..... ..... ..... 00 .... @8RR_XX4_uim3
33 changes: 22 additions & 11 deletions target/ppc/int_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1253,8 +1253,27 @@ void helper_vmulhud(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
mulu64(&discard, &r->u64[1], a->u64[1], b->u64[1]);
}

void helper_vperm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
ppc_avr_t *c)
void helper_XXPERMX(ppc_vsr_t *t, ppc_vsr_t *s0, ppc_vsr_t *s1, ppc_vsr_t *pcv,
target_ulong uim)
{
int i, idx;
ppc_vsr_t tmp = { .u64 = {0, 0} };

for (i = 0; i < ARRAY_SIZE(t->u8); i++) {
if ((pcv->VsrB(i) >> 5) == uim) {
idx = pcv->VsrB(i) & 0x1f;
if (idx < ARRAY_SIZE(t->u8)) {
tmp.VsrB(i) = s0->VsrB(idx);
} else {
tmp.VsrB(i) = s1->VsrB(idx - ARRAY_SIZE(t->u8));
}
}
}

*t = tmp;
}

void helper_VPERM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
{
ppc_avr_t result;
int i;
Expand All @@ -1272,8 +1291,7 @@ void helper_vperm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
*r = result;
}

void helper_vpermr(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
ppc_avr_t *c)
void helper_VPERMR(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
{
ppc_avr_t result;
int i;
Expand Down Expand Up @@ -1541,13 +1559,6 @@ VRLMI(vrlwmi, 32, u32, 1);
VRLMI(vrldnm, 64, u64, 0);
VRLMI(vrlwnm, 32, u32, 0);

void helper_vsel(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
ppc_avr_t *c)
{
r->u64[0] = (a->u64[0] & ~c->u64[0]) | (b->u64[0] & c->u64[0]);
r->u64[1] = (a->u64[1] & ~c->u64[1]) | (b->u64[1] & c->u64[1]);
}

void helper_vexptefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
{
int i;
Expand Down
69 changes: 53 additions & 16 deletions target/ppc/translate/vmx-impl.c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1548,28 +1548,65 @@ static void gen_vmladduhm(DisasContext *ctx)
tcg_temp_free_ptr(rd);
}

static void gen_vpermr(DisasContext *ctx)
static bool trans_VPERM(DisasContext *ctx, arg_VA *a)
{
TCGv_ptr ra, rb, rc, rd;
if (unlikely(!ctx->altivec_enabled)) {
gen_exception(ctx, POWERPC_EXCP_VPU);
return;
}
ra = gen_avr_ptr(rA(ctx->opcode));
rb = gen_avr_ptr(rB(ctx->opcode));
rc = gen_avr_ptr(rC(ctx->opcode));
rd = gen_avr_ptr(rD(ctx->opcode));
gen_helper_vpermr(cpu_env, rd, ra, rb, rc);
tcg_temp_free_ptr(ra);
tcg_temp_free_ptr(rb);
tcg_temp_free_ptr(rc);
tcg_temp_free_ptr(rd);
TCGv_ptr vrt, vra, vrb, vrc;

REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
REQUIRE_VECTOR(ctx);

vrt = gen_avr_ptr(a->vrt);
vra = gen_avr_ptr(a->vra);
vrb = gen_avr_ptr(a->vrb);
vrc = gen_avr_ptr(a->rc);

gen_helper_VPERM(vrt, vra, vrb, vrc);

tcg_temp_free_ptr(vrt);
tcg_temp_free_ptr(vra);
tcg_temp_free_ptr(vrb);
tcg_temp_free_ptr(vrc);

return true;
}

static bool trans_VPERMR(DisasContext *ctx, arg_VA *a)
{
TCGv_ptr vrt, vra, vrb, vrc;

REQUIRE_INSNS_FLAGS2(ctx, ISA300);
REQUIRE_VECTOR(ctx);

vrt = gen_avr_ptr(a->vrt);
vra = gen_avr_ptr(a->vra);
vrb = gen_avr_ptr(a->vrb);
vrc = gen_avr_ptr(a->rc);

gen_helper_VPERMR(vrt, vra, vrb, vrc);

tcg_temp_free_ptr(vrt);
tcg_temp_free_ptr(vra);
tcg_temp_free_ptr(vrb);
tcg_temp_free_ptr(vrc);

return true;
}
Comment on lines +1551 to +1593

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about merging these two functions using TRANS_FLAGS2 from #55 ?


static bool trans_VSEL(DisasContext *ctx, arg_VA *a)
{
REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
REQUIRE_VECTOR(ctx);

tcg_gen_gvec_bitsel(MO_64, avr_full_offset(a->vrt), avr_full_offset(a->rc),
avr_full_offset(a->vrb), avr_full_offset(a->vra),
16, 16);

return true;
}

GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
GEN_VAFORM_PAIRED(vsel, vperm, 21)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm since vsel and vperm are defined together, maybe merge this commit and the previous one?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to keep small commits to ease the review. Would it be better if I add a comment in the previous commit telling that the helper and other vsel stuff is removed here? Or should I squash these commits anyway?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unfortunate that they were implemented so tied together. Due to this, I would squash the 2 commits, taking into consideration that they're simple enough. To me, it causes more confusion to keep them separate than to squash them in a single one.

GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)

GEN_VXFORM_NOA(vclzb, 1, 28)
Expand Down
2 changes: 0 additions & 2 deletions target/ppc/translate/vmx-ops.c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ GEN_VXFORM_300_EO(vctzw, 0x01, 0x18, 0x1E),
GEN_VXFORM_300_EO(vctzd, 0x01, 0x18, 0x1F),
GEN_VXFORM_300_EO(vclzlsbb, 0x01, 0x18, 0x0),
GEN_VXFORM_300_EO(vctzlsbb, 0x01, 0x18, 0x1),
GEN_VXFORM_300(vpermr, 0x1D, 0xFF),

#define GEN_VXFORM_NOA(name, opc2, opc3) \
GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
Expand Down Expand Up @@ -276,7 +275,6 @@ GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
GEN_VAFORM_PAIRED(vsel, vperm, 21),
GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),

GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207),
Expand Down
Loading