Skip to content

Commit

Permalink
add _sve_xunpk & remove dead code
Browse files Browse the repository at this point in the history
Change-Id: Ic19836feb8a73ea7e65443794f2a0eb1363f6e2f
  • Loading branch information
Eric Liu committed Nov 21, 2023
1 parent 4fb3128 commit 68748e7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 68 deletions.
81 changes: 38 additions & 43 deletions src/hotspot/cpu/aarch64/assembler_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2196,41 +2196,20 @@ void mvnw(Register Rd, Register Rm,

#undef INSN

enum sign_kind { SIGNED, UNSIGNED };

private:
void _xcvtf_scalar_integer(sign_kind sign, unsigned sz,
FloatRegister Rd, FloatRegister Rn) {
starti;
f(0b01, 31, 30), f(sign == SIGNED ? 0 : 1, 29);
f(0b111100, 27, 23), f((sz >> 1) & 1, 22), f(0b100001110110, 21, 10);
rf(Rn, 5), rf(Rd, 0);
}

public:
#define INSN(NAME, sign, sz) \
void NAME(FloatRegister Rd, FloatRegister Rn) { \
_xcvtf_scalar_integer(sign, sz, Rd, Rn); \
}

INSN(scvtfs, SIGNED, 0);
INSN(scvtfd, SIGNED, 1);

#undef INSN

private:
void _xcvtf_vector_integer(sign_kind sign, SIMD_Arrangement T,
void _xcvtf_vector_integer(bool is_unsigned, SIMD_Arrangement T,
FloatRegister Rd, FloatRegister Rn) {
assert(T == T2S || T == T4S || T == T2D, "invalid arrangement");
starti;
f(0, 31), f(T & 1, 30), f(sign == SIGNED ? 0 : 1, 29);
f(0, 31), f(T & 1, 30), f(is_unsigned ? 1 : 0, 29);
f(0b011100, 28, 23), f((T >> 1) & 1, 22), f(0b100001110110, 21, 10);
rf(Rn, 5), rf(Rd, 0);
}

public:

void scvtfv(SIMD_Arrangement T, FloatRegister Rd, FloatRegister Rn) {
_xcvtf_vector_integer(SIGNED, T, Rd, Rn);
_xcvtf_vector_integer(/* is_unsigned */ false, T, Rd, Rn);
}

// Floating-point compare
Expand Down Expand Up @@ -2991,8 +2970,8 @@ template<typename R, typename... Rx>

#undef INSN

private:
void _xshll(sign_kind sign, FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
protected:
void _xshll(bool is_unsigned, FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
starti;
/* The encodings for the immh:immb fields (bits 22:16) are
* 0001 xxx 8H, 8B/16B shift = xxx
Expand All @@ -3002,20 +2981,20 @@ template<typename R, typename... Rx>
*/
assert((Tb >> 1) + 1 == (Ta >> 1), "Incompatible arrangement");
assert((1 << ((Tb>>1)+3)) > shift, "Invalid shift value");
f(0, 31), f(Tb & 1, 30), f(sign == SIGNED ? 0 : 1, 29), f(0b011110, 28, 23);
f(0, 31), f(Tb & 1, 30), f(is_unsigned ? 1 : 0, 29), f(0b011110, 28, 23);
f((1 << ((Tb>>1)+3))|shift, 22, 16);
f(0b101001, 15, 10), rf(Vn, 5), rf(Vd, 0);
}

public:
void ushll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
assert(Tb == T8B || Tb == T4H || Tb == T2S, "invalid arrangement");
_xshll(UNSIGNED, Vd, Ta, Vn, Tb, shift);
_xshll(/* is_unsigned */ true, Vd, Ta, Vn, Tb, shift);
}

void ushll2(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
assert(Tb == T16B || Tb == T8H || Tb == T4S, "invalid arrangement");
_xshll(UNSIGNED, Vd, Ta, Vn, Tb, shift);
_xshll(/* is_unsigned */ true, Vd, Ta, Vn, Tb, shift);
}

void uxtl(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb) {
Expand All @@ -3024,12 +3003,12 @@ template<typename R, typename... Rx>

void sshll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
assert(Tb == T8B || Tb == T4H || Tb == T2S, "invalid arrangement");
_xshll(SIGNED, Vd, Ta, Vn, Tb, shift);
_xshll(/* is_unsigned */ false, Vd, Ta, Vn, Tb, shift);
}

void sshll2(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) {
assert(Tb == T16B || Tb == T8H || Tb == T4S, "invalid arrangement");
_xshll(SIGNED, Vd, Ta, Vn, Tb, shift);
_xshll(/* is_unsigned */ false, Vd, Ta, Vn, Tb, shift);
}

void sxtl(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb) {
Expand Down Expand Up @@ -3862,19 +3841,35 @@ template<typename R, typename... Rx>
}

// SVE unpack vector elements
#define INSN(NAME, op) \
void NAME(FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) { \
starti; \
assert(T != B && T != Q, "invalid size"); \
f(0b00000101, 31, 24), f(T, 23, 22), f(0b1100, 21, 18); \
f(op, 17, 16), f(0b001110, 15, 10), rf(Zn, 5), rf(Zd, 0); \
protected:
void _sve_xunpk(bool is_unsigned, bool is_high, FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) {
starti;
assert(T != B && T != Q, "invalid size");
f(0b00000101, 31, 24), f(T, 23, 22), f(0b1100, 21, 18);
f(is_unsigned ? 1 : 0, 17), f(is_high ? 1 : 0, 16),
f(0b001110, 15, 10), rf(Zn, 5), rf(Zd, 0);
}

INSN(sve_uunpkhi, 0b11); // Signed unpack and extend half of vector - high half
INSN(sve_uunpklo, 0b10); // Signed unpack and extend half of vector - low half
INSN(sve_sunpkhi, 0b01); // Unsigned unpack and extend half of vector - high half
INSN(sve_sunpklo, 0b00); // Unsigned unpack and extend half of vector - low half
#undef INSN
public:
// Unsigned unpack and extend half of vector - high half
void sve_uunpkhi(FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) {
_sve_xunpk(/* is_unsigned */ true, /* is_high */ true, Zd, T, Zn);
}

// Unsigned unpack and extend half of vector - low half
void sve_uunpklo(FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) {
_sve_xunpk(/* is_unsigned */ true, /* is_high */ false, Zd, T, Zn);
}

// Signed unpack and extend half of vector - high half
void sve_sunpkhi(FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) {
_sve_xunpk(/* is_unsigned */ false, /* is_high */ true, Zd, T, Zn);
}

// Signed unpack and extend half of vector - low half
void sve_sunpklo(FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) {
_sve_xunpk(/* is_unsigned */ false, /* is_high */ false, Zd, T, Zn);
}

// SVE unpack predicate elements
#define INSN(NAME, op) \
Expand Down
40 changes: 15 additions & 25 deletions src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1337,33 +1337,28 @@ void C2_MacroAssembler::sve_vmask_lasttrue(Register dst, BasicType bt, PRegister
subw(dst, rscratch1, dst);
}

typedef void (C2_MacroAssembler::* xtl_insn)(FloatRegister Vd, Assembler::SIMD_Arrangement Ta,
FloatRegister Vn, Assembler::SIMD_Arrangement Tb);

// Extend integer vector src to dst with the same lane count
// but larger element size, e.g. 4B -> 4I
void C2_MacroAssembler::neon_vector_extend(FloatRegister dst, BasicType dst_bt, unsigned dst_vlen_in_bytes,
FloatRegister src, BasicType src_bt, bool is_unsigned) {
xtl_insn ext = is_unsigned ? &C2_MacroAssembler::uxtl : &C2_MacroAssembler::sxtl;
if (src_bt == T_BYTE) {
if (dst_bt == T_SHORT) {
// 4B/8B to 4S/8S
assert(dst_vlen_in_bytes == 8 || dst_vlen_in_bytes == 16, "unsupported");
(this->*ext)(dst, T8H, src, T8B);
_xshll(is_unsigned, dst, T8H, src, T8B, 0);
} else {
// 4B to 4I
assert(dst_vlen_in_bytes == 16 && dst_bt == T_INT, "unsupported");
(this->*ext)(dst, T8H, src, T8B);
(this->*ext)(dst, T4S, dst, T4H);
_xshll(is_unsigned, dst, T8H, src, T8B, 0);
_xshll(is_unsigned, dst, T4S, dst, T4H, 0);
}
} else if (src_bt == T_SHORT) {
// 4S to 4I
assert(dst_vlen_in_bytes == 16 && dst_bt == T_INT, "unsupported");
(this->*ext)(dst, T4S, src, T4H);
_xshll(is_unsigned, dst, T4S, src, T4H, 0);
} else if (src_bt == T_INT) {
// 2I to 2L
assert(dst_vlen_in_bytes == 16 && dst_bt == T_LONG, "unsupported");
(this->*ext)(dst, T2D, src, T2S);
_xshll(is_unsigned, dst, T2D, src, T2S, 0);
} else {
ShouldNotReachHere();
}
Expand Down Expand Up @@ -1396,42 +1391,37 @@ void C2_MacroAssembler::neon_vector_narrow(FloatRegister dst, BasicType dst_bt,
}
}

typedef void (C2_MacroAssembler::* unpklo_insn)(FloatRegister Zd, Assembler::SIMD_RegVariant T,
FloatRegister Zn);

void C2_MacroAssembler::sve_vector_extend(FloatRegister dst, SIMD_RegVariant dst_size,
FloatRegister src, SIMD_RegVariant src_size,
bool is_unsigned) {
assert(dst_size > src_size && dst_size <= D && src_size <= S, "invalid element size");

unpklo_insn unpklo = is_unsigned ? &C2_MacroAssembler::sve_uunpklo : &C2_MacroAssembler::sve_sunpklo;

if (src_size == B) {
switch (dst_size) {
case H:
(this->*unpklo)(dst, H, src);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, H, src);
break;
case S:
(this->*unpklo)(dst, H, src);
(this->*unpklo)(dst, S, dst);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, H, src);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, S, dst);
break;
case D:
(this->*unpklo)(dst, H, src);
(this->*unpklo)(dst, S, dst);
(this->*unpklo)(dst, D, dst);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, H, src);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, S, dst);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, D, dst);
break;
default:
ShouldNotReachHere();
}
} else if (src_size == H) {
if (dst_size == S) {
(this->*unpklo)(dst, S, src);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, S, src);
} else { // D
(this->*unpklo)(dst, S, src);
(this->*unpklo)(dst, D, dst);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, S, src);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, D, dst);
}
} else if (src_size == S) {
(this->*unpklo)(dst, D, src);
_sve_xunpk(is_unsigned, /* is_high */ false, dst, D, src);
}
}

Expand Down

0 comments on commit 68748e7

Please sign in to comment.