Skip to content

Commit 1bbaa31

Browse files
modulovaluedart-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
[vm] x64: add pshufd
Needed to improve the performance of Int32x4.shuffle and Float32x4.shuffle. Issue: #64170 Issue: #64345 TEST=vm/cc/Assembler_Pshufd Change-Id: Icadaffff8e418bf90168daf428ca533f21f70da0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/559000 Auto-Submit: Modestas Valauskas <valauskasmodestas@gmail.com> Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Alexander Aprelev <aam@google.com> Reviewed-by: Slava Egorov <vegorov@google.com>
1 parent 2a3dc52 commit 1bbaa31

4 files changed

Lines changed: 49 additions & 0 deletions

File tree

‎runtime/vm/compiler/assembler/assembler_x64.cc‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,13 @@ void Assembler::shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm) {
573573
EmitUint8(imm.value());
574574
}
575575

576+
void Assembler::pshufd(XmmRegister dst, XmmRegister src, const Immediate& imm) {
577+
EmitL(dst, src, 0x70, 0x0F, 0x66);
578+
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
579+
ASSERT(imm.is_uint8());
580+
EmitUint8(imm.value());
581+
}
582+
576583
void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) {
577584
ASSERT(src <= XMM15);
578585
ASSERT(dst <= XMM15);

‎runtime/vm/compiler/assembler/assembler_x64.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ class Assembler : public AssemblerBase {
562562
void negatepd(XmmRegister dst, XmmRegister src);
563563
void abspd(XmmRegister dst, XmmRegister src);
564564
void shufpd(XmmRegister dst, XmmRegister src, const Immediate& mask);
565+
void pshufd(XmmRegister dst, XmmRegister src, const Immediate& mask);
565566

566567
enum RoundingMode {
567568
kRoundToNearest = 0x0,

‎runtime/vm/compiler/assembler/assembler_x64_test.cc‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5415,6 +5415,41 @@ ASSEMBLER_TEST_RUN(Ptest, test) {
54155415
"ret\n");
54165416
}
54175417

5418+
ASSEMBLER_TEST_GENERATE(Pshufd, assembler) {
5419+
static const struct ALIGN16 {
5420+
uint32_t a;
5421+
uint32_t b;
5422+
uint32_t c;
5423+
uint32_t d;
5424+
} constant1 = {0x01234567, 0x89ABCDEF, 0x76543210, 0xFEDCBA98};
5425+
__ movq(RAX, CallingConventions::kArg1Reg);
5426+
__ movq(RDX, Immediate(reinterpret_cast<intptr_t>(&constant1)));
5427+
__ movups(XMM0, Address(RDX, 0));
5428+
__ pshufd(XMM1, XMM0, Immediate(0x9C));
5429+
__ movups(Address(RAX, 0), XMM1);
5430+
__ movups(Address(RAX, 16), XMM0);
5431+
__ ret();
5432+
}
5433+
5434+
ASSEMBLER_TEST_RUN(Pshufd, test) {
5435+
typedef void (*PshufdCode)(uint32_t* result);
5436+
uint32_t result[8] = {0, 0, 0, 0, 0, 0, 0, 0};
5437+
reinterpret_cast<PshufdCode>(test->entry())(result);
5438+
EXPECT_EQ(0x01234567u, result[0]);
5439+
EXPECT_EQ(0xFEDCBA98u, result[1]);
5440+
EXPECT_EQ(0x89ABCDEFu, result[2]);
5441+
EXPECT_EQ(0x76543210u, result[3]);
5442+
EXPECT_EQ(0x01234567u, result[4]);
5443+
EXPECT_EQ(0x89ABCDEFu, result[5]);
5444+
EXPECT_EQ(0x76543210u, result[6]);
5445+
EXPECT_EQ(0xFEDCBA98u, result[7]);
5446+
EXPECT_DISASSEMBLY_ENDS_WITH(
5447+
"pshufd xmm1,xmm0 [9c]\n"
5448+
"movups [rax],xmm1\n"
5449+
"movups [rax+0x10],xmm0\n"
5450+
"ret\n");
5451+
}
5452+
54185453
ASSEMBLER_TEST_GENERATE(SquareRootDouble, assembler) {
54195454
__ sqrtsd(XMM0, XMM0);
54205455
__ ret();

‎runtime/vm/compiler/assembler/disassembler_x86.cc‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,12 @@ int DisassemblerX64::TwoByteOpcodeInstruction(uint8_t* data) {
12901290
current += PrintRightXMMOperand(current);
12911291
Print(" [%x]", *current);
12921292
current++;
1293+
} else if (opcode == 0x70) {
1294+
get_modrm(*current, &mod, &regop, &rm);
1295+
Print("pshufd %s,", NameOfXMMRegister(regop));
1296+
current += PrintRightXMMOperand(current);
1297+
Print(" [%x]", *current);
1298+
current++;
12931299
} else if (opcode == 0x3A) {
12941300
uint8_t third_byte = *current;
12951301
current = data + 3;

0 commit comments

Comments
 (0)