x86_64: Add UD2 instruction and test.

This instruction is useful to guard unreachable code that we have to
generate for some rason, but we should never execute.

Bug: 71781600
Test: $ANDROID_HOST_OUT/nativetest64/art_compiler_host_tests/art_compiler_host_tests --gtest_filter='*AssemblerX86_64Test.Ud2*'
Change-Id: Ibd106c0091bd3fd958ab34f0b6d90382773aad79
diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc
index 5edc309..966d9e4 100644
--- a/compiler/utils/x86_64/assembler_x86_64.cc
+++ b/compiler/utils/x86_64/assembler_x86_64.cc
@@ -5268,6 +5268,11 @@
   EmitUint8(0xA7);
 }
 
+void X86_64Assembler::ud2() {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitUint8(0x0F);
+  EmitUint8(0x0B);
+}
 
 void X86_64Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
   // TODO: Need to have a code constants table.
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index 2cbc9d9..7d61500 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -982,6 +982,8 @@
   void repe_cmpsq();
   void rep_movsw();
 
+  void ud2();
+
   //
   // Macros for High-level operations.
   //
diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc
index 4c07354..53febca 100644
--- a/compiler/utils/x86_64/assembler_x86_64_test.cc
+++ b/compiler/utils/x86_64/assembler_x86_64_test.cc
@@ -2411,6 +2411,12 @@
   DriverStr(expected, "Repecmpsq");
 }
 
+TEST_F(AssemblerX86_64Test, Ud2) {
+  GetAssembler()->ud2();
+  const char* expected = "ud2\n";
+  DriverStr(expected, "Ud2");
+}
+
 TEST_F(AssemblerX86_64Test, Cmpb) {
   DriverStr(RepeatAI(&x86_64::X86_64Assembler::cmpb,
                      /*imm_bytes*/ 1U,