MIPS32: Implement HSelect
Test: booted MIPS32R2 in QEMU
Test: test-art-target-run-test-optimizing (MIPS32R2) on CI20
Test: booted MIPS64 (with 2nd arch MIPS32R6) in QEMU
Test: test-art-target-run-test-optimizing (MIPS32R6) in QEMU
Test: test-art-host-gtest
Change-Id: I8a8127d8d29cb5df84ed6f4fd4478f8d889e5cb7
diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc
index b972c70..b29974c 100644
--- a/compiler/utils/mips/assembler_mips.cc
+++ b/compiler/utils/mips/assembler_mips.cc
@@ -192,6 +192,13 @@
DsFsmInstr(instruction, 0, 0, (1u << in1_out), (1u << in1_out) | (1u << in2) | (1u << in3), 0, 0);
}
+void MipsAssembler::DsFsmInstrFffr(uint32_t instruction,
+ FRegister in1_out,
+ FRegister in2,
+ Register in3) {
+ DsFsmInstr(instruction, 0, (1u << in3), (1u << in1_out), (1u << in1_out) | (1u << in2), 0, 0);
+}
+
void MipsAssembler::DsFsmInstrRf(uint32_t instruction, Register out, FRegister in) {
DsFsmInstr(instruction, (1u << out), 0, 0, (1u << in), 0, 0);
}
@@ -1446,6 +1453,26 @@
cc);
}
+void MipsAssembler::MovzS(FRegister fd, FRegister fs, Register rt) {
+ CHECK(!IsR6());
+ DsFsmInstrFffr(EmitFR(0x11, 0x10, static_cast<FRegister>(rt), fs, fd, 0x12), fd, fs, rt);
+}
+
+void MipsAssembler::MovzD(FRegister fd, FRegister fs, Register rt) {
+ CHECK(!IsR6());
+ DsFsmInstrFffr(EmitFR(0x11, 0x11, static_cast<FRegister>(rt), fs, fd, 0x12), fd, fs, rt);
+}
+
+void MipsAssembler::MovnS(FRegister fd, FRegister fs, Register rt) {
+ CHECK(!IsR6());
+ DsFsmInstrFffr(EmitFR(0x11, 0x10, static_cast<FRegister>(rt), fs, fd, 0x13), fd, fs, rt);
+}
+
+void MipsAssembler::MovnD(FRegister fd, FRegister fs, Register rt) {
+ CHECK(!IsR6());
+ DsFsmInstrFffr(EmitFR(0x11, 0x11, static_cast<FRegister>(rt), fs, fd, 0x13), fd, fs, rt);
+}
+
void MipsAssembler::SelS(FRegister fd, FRegister fs, FRegister ft) {
CHECK(IsR6());
DsFsmInstrFfff(EmitFR(0x11, 0x10, ft, fs, fd, 0x10), fd, fs, ft);
@@ -1456,6 +1483,26 @@
DsFsmInstrFfff(EmitFR(0x11, 0x11, ft, fs, fd, 0x10), fd, fs, ft);
}
+void MipsAssembler::SeleqzS(FRegister fd, FRegister fs, FRegister ft) {
+ CHECK(IsR6());
+ DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x14), fd, fs, ft);
+}
+
+void MipsAssembler::SeleqzD(FRegister fd, FRegister fs, FRegister ft) {
+ CHECK(IsR6());
+ DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x14), fd, fs, ft);
+}
+
+void MipsAssembler::SelnezS(FRegister fd, FRegister fs, FRegister ft) {
+ CHECK(IsR6());
+ DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x17), fd, fs, ft);
+}
+
+void MipsAssembler::SelnezD(FRegister fd, FRegister fs, FRegister ft) {
+ CHECK(IsR6());
+ DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x17), fd, fs, ft);
+}
+
void MipsAssembler::ClassS(FRegister fd, FRegister fs) {
CHECK(IsR6());
DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x1b), fd, fs, fs);
diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h
index b932fb8..800dc5f 100644
--- a/compiler/utils/mips/assembler_mips.h
+++ b/compiler/utils/mips/assembler_mips.h
@@ -414,8 +414,16 @@
void MovfD(FRegister fd, FRegister fs, int cc = 0); // R2
void MovtS(FRegister fd, FRegister fs, int cc = 0); // R2
void MovtD(FRegister fd, FRegister fs, int cc = 0); // R2
+ void MovzS(FRegister fd, FRegister fs, Register rt); // R2
+ void MovzD(FRegister fd, FRegister fs, Register rt); // R2
+ void MovnS(FRegister fd, FRegister fs, Register rt); // R2
+ void MovnD(FRegister fd, FRegister fs, Register rt); // R2
void SelS(FRegister fd, FRegister fs, FRegister ft); // R6
void SelD(FRegister fd, FRegister fs, FRegister ft); // R6
+ void SeleqzS(FRegister fd, FRegister fs, FRegister ft); // R6
+ void SeleqzD(FRegister fd, FRegister fs, FRegister ft); // R6
+ void SelnezS(FRegister fd, FRegister fs, FRegister ft); // R6
+ void SelnezD(FRegister fd, FRegister fs, FRegister ft); // R6
void ClassS(FRegister fd, FRegister fs); // R6
void ClassD(FRegister fd, FRegister fs); // R6
void MinS(FRegister fd, FRegister fs, FRegister ft); // R6
@@ -1257,6 +1265,7 @@
void DsFsmInstrRrrr(uint32_t instruction, Register in1_out, Register in2, Register in3);
void DsFsmInstrFff(uint32_t instruction, FRegister out, FRegister in1, FRegister in2);
void DsFsmInstrFfff(uint32_t instruction, FRegister in1_out, FRegister in2, FRegister in3);
+ void DsFsmInstrFffr(uint32_t instruction, FRegister in1_out, FRegister in2, Register in3);
void DsFsmInstrRf(uint32_t instruction, Register out, FRegister in);
void DsFsmInstrFr(uint32_t instruction, FRegister out, Register in);
void DsFsmInstrFR(uint32_t instruction, FRegister in1, Register in2);
diff --git a/compiler/utils/mips/assembler_mips32r6_test.cc b/compiler/utils/mips/assembler_mips32r6_test.cc
index 750a94d..3ef2f94 100644
--- a/compiler/utils/mips/assembler_mips32r6_test.cc
+++ b/compiler/utils/mips/assembler_mips32r6_test.cc
@@ -349,6 +349,26 @@
DriverStr(RepeatFFF(&mips::MipsAssembler::SelD, "sel.d ${reg1}, ${reg2}, ${reg3}"), "sel.d");
}
+TEST_F(AssemblerMIPS32r6Test, SeleqzS) {
+ DriverStr(RepeatFFF(&mips::MipsAssembler::SeleqzS, "seleqz.s ${reg1}, ${reg2}, ${reg3}"),
+ "seleqz.s");
+}
+
+TEST_F(AssemblerMIPS32r6Test, SeleqzD) {
+ DriverStr(RepeatFFF(&mips::MipsAssembler::SeleqzD, "seleqz.d ${reg1}, ${reg2}, ${reg3}"),
+ "seleqz.d");
+}
+
+TEST_F(AssemblerMIPS32r6Test, SelnezS) {
+ DriverStr(RepeatFFF(&mips::MipsAssembler::SelnezS, "selnez.s ${reg1}, ${reg2}, ${reg3}"),
+ "selnez.s");
+}
+
+TEST_F(AssemblerMIPS32r6Test, SelnezD) {
+ DriverStr(RepeatFFF(&mips::MipsAssembler::SelnezD, "selnez.d ${reg1}, ${reg2}, ${reg3}"),
+ "selnez.d");
+}
+
TEST_F(AssemblerMIPS32r6Test, ClassS) {
DriverStr(RepeatFF(&mips::MipsAssembler::ClassS, "class.s ${reg1}, ${reg2}"), "class.s");
}
diff --git a/compiler/utils/mips/assembler_mips_test.cc b/compiler/utils/mips/assembler_mips_test.cc
index a9abf2f..75149cf 100644
--- a/compiler/utils/mips/assembler_mips_test.cc
+++ b/compiler/utils/mips/assembler_mips_test.cc
@@ -667,6 +667,22 @@
"MovtD");
}
+TEST_F(AssemblerMIPSTest, MovzS) {
+ DriverStr(RepeatFFR(&mips::MipsAssembler::MovzS, "movz.s ${reg1}, ${reg2}, ${reg3}"), "MovzS");
+}
+
+TEST_F(AssemblerMIPSTest, MovzD) {
+ DriverStr(RepeatFFR(&mips::MipsAssembler::MovzD, "movz.d ${reg1}, ${reg2}, ${reg3}"), "MovzD");
+}
+
+TEST_F(AssemblerMIPSTest, MovnS) {
+ DriverStr(RepeatFFR(&mips::MipsAssembler::MovnS, "movn.s ${reg1}, ${reg2}, ${reg3}"), "MovnS");
+}
+
+TEST_F(AssemblerMIPSTest, MovnD) {
+ DriverStr(RepeatFFR(&mips::MipsAssembler::MovnD, "movn.d ${reg1}, ${reg2}, ${reg3}"), "MovnD");
+}
+
TEST_F(AssemblerMIPSTest, CvtSW) {
DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsw, "cvt.s.w ${reg1}, ${reg2}"), "CvtSW");
}