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);