ir: Add opcode for reversing bits in a vector

This commit is contained in:
Lioncash 2018-04-03 08:46:01 -04:00 committed by MerryMage
parent 9de60b60bb
commit 64b1f2d468
4 changed files with 49 additions and 0 deletions

View file

@ -1276,6 +1276,49 @@ void EmitX64::EmitVectorPopulationCount(EmitContext& ctx, IR::Inst* inst) {
});
}
void EmitX64::EmitVectorReverseBits(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const Xbyak::Xmm data = ctx.reg_alloc.UseScratchXmm(args[0]);
const Xbyak::Xmm high_nibble_reg = ctx.reg_alloc.ScratchXmm();
code.movdqa(high_nibble_reg, code.MConst(xword, 0xF0F0F0F0F0F0F0F0, 0xF0F0F0F0F0F0F0F0));
code.pand(high_nibble_reg, data);
code.pxor(data, high_nibble_reg);
code.psrld(high_nibble_reg, 4);
if (code.DoesCpuSupport(Xbyak::util::Cpu::tSSSE3)) {
// High lookup
const Xbyak::Xmm high_reversed_reg = ctx.reg_alloc.ScratchXmm();
code.movdqa(high_reversed_reg, code.MConst(xword, 0xE060A020C0408000, 0xF070B030D0509010));
code.pshufb(high_reversed_reg, data);
// Low lookup (low nibble equivalent of the above)
code.movdqa(data, code.MConst(xword, 0x0E060A020C040800, 0x0F070B030D050901));
code.pshufb(data, high_nibble_reg);
code.por(data, high_reversed_reg);
} else {
code.pslld(data, 4);
code.por(data, high_nibble_reg);
code.movdqa(high_nibble_reg, code.MConst(xword, 0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC));
code.pand(high_nibble_reg, data);
code.pxor(data, high_nibble_reg);
code.psrld(high_nibble_reg, 2);
code.pslld(data, 2);
code.por(data, high_nibble_reg);
code.movdqa(high_nibble_reg, code.MConst(xword, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA));
code.pand(high_nibble_reg, data);
code.pxor(data, high_nibble_reg);
code.psrld(high_nibble_reg, 1);
code.paddd(data, data);
code.por(data, high_nibble_reg);
}
ctx.reg_alloc.DefineValue(inst, data);
}
enum class ShuffleType {
LowHalfwords,
HighHalfwords,

View file

@ -1143,6 +1143,10 @@ U128 IREmitter::VectorPopulationCount(const U128& a) {
return Inst<U128>(Opcode::VectorPopulationCount, a);
}
U128 IREmitter::VectorReverseBits(const U128& a) {
return Inst<U128>(Opcode::VectorReverseBits, a);
}
U128 IREmitter::VectorShuffleHighHalfwords(const U128& a, u8 mask) {
return Inst<U128>(Opcode::VectorShuffleHighHalfwords, a, mask);
}

View file

@ -242,6 +242,7 @@ public:
U128 VectorPairedAdd(size_t esize, const U128& a, const U128& b);
U128 VectorPairedAddLower(size_t esize, const U128& a, const U128& b);
U128 VectorPopulationCount(const U128& a);
U128 VectorReverseBits(const U128& a);
U128 VectorShuffleHighHalfwords(const U128& a, u8 mask);
U128 VectorShuffleLowHalfwords(const U128& a, u8 mask);
U128 VectorShuffleWords(const U128& a, u8 mask);

View file

@ -296,6 +296,7 @@ OPCODE(VectorPairedAdd16, T::U128, T::U128, T::U
OPCODE(VectorPairedAdd32, T::U128, T::U128, T::U128 )
OPCODE(VectorPairedAdd64, T::U128, T::U128, T::U128 )
OPCODE(VectorPopulationCount, T::U128, T::U128 )
OPCODE(VectorReverseBits, T::U128, T::U128 )
OPCODE(VectorShuffleHighHalfwords, T::U128, T::U128, T::U8 )
OPCODE(VectorShuffleLowHalfwords, T::U128, T::U128, T::U8 )
OPCODE(VectorShuffleWords, T::U128, T::U128, T::U8 )