Merge "MIPS: Add asub_s/u.df"
diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc
index 9545ca6..eb75f8b 100644
--- a/compiler/utils/mips/assembler_mips.cc
+++ b/compiler/utils/mips/assembler_mips.cc
@@ -3181,6 +3181,70 @@
                 static_cast<FRegister>(wt));
 }
 
+void MipsAssembler::Asub_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
+void MipsAssembler::Asub_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
+void MipsAssembler::Asub_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
+void MipsAssembler::Asub_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
+void MipsAssembler::Asub_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
+void MipsAssembler::Asub_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
+void MipsAssembler::Asub_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
+void MipsAssembler::Asub_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x11),
+                static_cast<FRegister>(wd),
+                static_cast<FRegister>(ws),
+                static_cast<FRegister>(wt));
+}
+
 void MipsAssembler::FmaddW(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
   CHECK(HasMsa());
   DsFsmInstrFff(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0x1b),
diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h
index c0ea29f..1c3097a 100644
--- a/compiler/utils/mips/assembler_mips.h
+++ b/compiler/utils/mips/assembler_mips.h
@@ -494,6 +494,14 @@
   void SubvH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void SubvW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void SubvD(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void MulvB(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void MulvH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void MulvW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
diff --git a/compiler/utils/mips/assembler_mips32r6_test.cc b/compiler/utils/mips/assembler_mips32r6_test.cc
index c76a568..937ee25 100644
--- a/compiler/utils/mips/assembler_mips32r6_test.cc
+++ b/compiler/utils/mips/assembler_mips32r6_test.cc
@@ -1757,6 +1757,46 @@
   DriverStr(RepeatVVV(&mips::MipsAssembler::SubvD, "subv.d ${reg1}, ${reg2}, ${reg3}"), "subv.d");
 }
 
+TEST_F(AssemblerMIPS32r6Test, Asub_sB) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_sB, "asub_s.b ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.b");
+}
+
+TEST_F(AssemblerMIPS32r6Test, Asub_sH) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_sH, "asub_s.h ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.h");
+}
+
+TEST_F(AssemblerMIPS32r6Test, Asub_sW) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_sW, "asub_s.w ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.w");
+}
+
+TEST_F(AssemblerMIPS32r6Test, Asub_sD) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_sD, "asub_s.d ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.d");
+}
+
+TEST_F(AssemblerMIPS32r6Test, Asub_uB) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_uB, "asub_u.b ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.b");
+}
+
+TEST_F(AssemblerMIPS32r6Test, Asub_uH) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_uH, "asub_u.h ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.h");
+}
+
+TEST_F(AssemblerMIPS32r6Test, Asub_uW) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_uW, "asub_u.w ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.w");
+}
+
+TEST_F(AssemblerMIPS32r6Test, Asub_uD) {
+  DriverStr(RepeatVVV(&mips::MipsAssembler::Asub_uD, "asub_u.d ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.d");
+}
+
 TEST_F(AssemblerMIPS32r6Test, MulvB) {
   DriverStr(RepeatVVV(&mips::MipsAssembler::MulvB, "mulv.b ${reg1}, ${reg2}, ${reg3}"), "mulv.b");
 }
diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc
index d8a4531..bf56877 100644
--- a/compiler/utils/mips64/assembler_mips64.cc
+++ b/compiler/utils/mips64/assembler_mips64.cc
@@ -1353,6 +1353,46 @@
   EmitMsa3R(0x1, 0x3, wt, ws, wd, 0xe);
 }
 
+void Mips64Assembler::Asub_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x11);
+}
+
+void Mips64Assembler::Asub_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x11);
+}
+
+void Mips64Assembler::Asub_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x11);
+}
+
+void Mips64Assembler::Asub_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x11);
+}
+
+void Mips64Assembler::Asub_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x11);
+}
+
+void Mips64Assembler::Asub_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x11);
+}
+
+void Mips64Assembler::Asub_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x11);
+}
+
+void Mips64Assembler::Asub_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
+  CHECK(HasMsa());
+  EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x11);
+}
+
 void Mips64Assembler::MulvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) {
   CHECK(HasMsa());
   EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x12);
diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h
index d67fb00..9f5e6aa 100644
--- a/compiler/utils/mips64/assembler_mips64.h
+++ b/compiler/utils/mips64/assembler_mips64.h
@@ -678,6 +678,14 @@
   void SubvH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void SubvW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void SubvD(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
+  void Asub_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void MulvB(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void MulvH(VectorRegister wd, VectorRegister ws, VectorRegister wt);
   void MulvW(VectorRegister wd, VectorRegister ws, VectorRegister wt);
diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc
index 164af78..d89ca3d 100644
--- a/compiler/utils/mips64/assembler_mips64_test.cc
+++ b/compiler/utils/mips64/assembler_mips64_test.cc
@@ -2947,6 +2947,46 @@
             "subv.d");
 }
 
+TEST_F(AssemblerMIPS64Test, Asub_sB) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_sB, "asub_s.b ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.b");
+}
+
+TEST_F(AssemblerMIPS64Test, Asub_sH) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_sH, "asub_s.h ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.h");
+}
+
+TEST_F(AssemblerMIPS64Test, Asub_sW) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_sW, "asub_s.w ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.w");
+}
+
+TEST_F(AssemblerMIPS64Test, Asub_sD) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_sD, "asub_s.d ${reg1}, ${reg2}, ${reg3}"),
+            "asub_s.d");
+}
+
+TEST_F(AssemblerMIPS64Test, Asub_uB) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_uB, "asub_u.b ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.b");
+}
+
+TEST_F(AssemblerMIPS64Test, Asub_uH) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_uH, "asub_u.h ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.h");
+}
+
+TEST_F(AssemblerMIPS64Test, Asub_uW) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_uW, "asub_u.w ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.w");
+}
+
+TEST_F(AssemblerMIPS64Test, Asub_uD) {
+  DriverStr(RepeatVVV(&mips64::Mips64Assembler::Asub_uD, "asub_u.d ${reg1}, ${reg2}, ${reg3}"),
+            "asub_u.d");
+}
+
 TEST_F(AssemblerMIPS64Test, MulvB) {
   DriverStr(RepeatVVV(&mips64::Mips64Assembler::MulvB, "mulv.b ${reg1}, ${reg2}, ${reg3}"),
             "mulv.b");
diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc
index 7c6a325..2c800e7 100644
--- a/disassembler/disassembler_mips.cc
+++ b/disassembler/disassembler_mips.cc
@@ -449,6 +449,8 @@
   { kMsaMask | (0x1f << 21), kMsa | (0x3 << 21) | 0x1e, "xor.v", "kmn" },
   { kMsaMask | (0x7 << 23), kMsa | (0x0 << 23) | 0xe, "addv", "Vkmn" },
   { kMsaMask | (0x7 << 23), kMsa | (0x1 << 23) | 0xe, "subv", "Vkmn" },
+  { kMsaMask | (0x7 << 23), kMsa | (0x4 << 23) | 0x11, "asub_s", "Vkmn" },
+  { kMsaMask | (0x7 << 23), kMsa | (0x5 << 23) | 0x11, "asub_u", "Vkmn" },
   { kMsaMask | (0x7 << 23), kMsa | (0x0 << 23) | 0x12, "mulv", "Vkmn" },
   { kMsaMask | (0x7 << 23), kMsa | (0x4 << 23) | 0x12, "div_s", "Vkmn" },
   { kMsaMask | (0x7 << 23), kMsa | (0x5 << 23) | 0x12, "div_u", "Vkmn" },