diff --git a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp --- a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp @@ -1180,7 +1180,9 @@ // If any AArch64 variant, enable latest ISA with any optional // extensions like MTE. if (triple.isAArch64()) { - features_str += "+v9.3a,+mte"; + features_str += "+v9.3a,+mte,+sm4,+sha2,+sha3,+aes,+fp16fml,+sve2-aes,+" + "sve2-sm4,+sve2-sha3,+sve2-bitperm,+f32mm,+f64mm,+tme,+" + "ls64,+sme,+sme-f64,+sme-i64,+spe,+rand,+brbe"; if (triple.getVendor() == llvm::Triple::Apple) cpu = "apple-latest"; diff --git a/lldb/test/API/python_api/disassemble-raw-data/aarch64-extensions/TestDisassembleAArch64Extensions.py b/lldb/test/API/python_api/disassemble-raw-data/aarch64-extensions/TestDisassembleAArch64Extensions.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/python_api/disassemble-raw-data/aarch64-extensions/TestDisassembleAArch64Extensions.py @@ -0,0 +1,141 @@ +""" +Use lldb Python API to disassemble raw bytes and check that all current +AArch64 extensions are recognised. +""" + +from __future__ import print_function + +from io import StringIO +import sys + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestDisassembleAArch64Extensions(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @no_debug_info_test + @skipIfLLVMTargetMissing("AArch64") + def test_disassemble_extensions(self): + """Test disassembling one thing from each extension.""" + target = self.dbg.CreateTargetWithFileAndTargetTriple("", "aarch64-linux-gnueabihf") + self.assertTrue(target, VALID_TARGET) + + # This is generated from extensions.s. We do not compile that file for this test + # because we cannot be sure the test compiler supports every extension. + + raw_bytes = bytearray([ + 0x00, 0x40, 0xc0, 0x1a, + 0xe0, 0x03, 0xa0, 0x38, + 0x20, 0x84, 0x42, 0x2e, + 0x00, 0x84, 0xc0, 0xce, + 0x00, 0x00, 0x20, 0xce, + 0x00, 0x40, 0x00, 0x5e, + 0x00, 0x58, 0x28, 0x4e, + 0x20, 0x94, 0x82, 0x0e, + 0x00, 0xc0, 0x22, 0x1e, + 0x00, 0xbc, 0xa0, 0x4e, + 0x41, 0xc0, 0xe0, 0x1e, + 0x20, 0xec, 0x22, 0x0e, + 0x3f, 0x22, 0x03, 0xd5, + 0xa0, 0x54, 0x18, 0xd5, + 0xff, 0xbf, 0x56, 0x04, + 0x20, 0x0c, 0xdf, 0x44, + 0xe0, 0xe7, 0x22, 0x45, + 0x00, 0xe0, 0x23, 0x45, + 0x00, 0xf4, 0x20, 0x45, + 0x20, 0xb4, 0x1f, 0x45, + 0x00, 0xc0, 0xbf, 0x38, + 0x00, 0x24, 0x3b, 0xd5, + 0x00, 0x10, 0xdf, 0x9a, + 0xc2, 0x42, 0x3b, 0xd5, + 0xff, 0x30, 0x03, 0xd5, + 0x80, 0x73, 0x0b, 0xd5, + 0x62, 0xfc, 0x44, 0x2e, + 0x01, 0xa6, 0x9f, 0x4e, + 0x20, 0xe4, 0xa2, 0x64, + 0x20, 0xe4, 0xe2, 0x64, + 0x7f, 0x30, 0x03, 0xd5, + 0xa0, 0xd1, 0x3f, 0xf8, + 0x9f, 0x72, 0x09, 0xd5, + 0x20, 0x00, 0xc1, 0xda, + 0x1f, 0x40, 0x00, 0xd5, + 0x00, 0x00, 0x90, 0xc0, + 0x00, 0x00, 0xc0, 0x80, + 0x00, 0x00, 0xd0, 0xc0, + 0x10, 0x00, 0x00, 0x54, + 0x40, 0x04, 0x01, 0x19, + 0x00, 0x9d, 0x3b, 0xd5, + ]) + + # Note that bc.eq uses a label which comes out as an offset. + assembly = """ + crc32b w0, w0, w0 + ldaddab w0, w0, [sp] + sqrdmlah v0.4h, v1.4h, v2.4h + sm4e v0.4s, v0.4s + bcax v0.16b, v0.16b, v0.16b, v0.16b + sha256h q0, q0, v0.4s + aesd v0.16b, v0.16b + sdot v0.2s, v1.8b, v2.8b + fcvt d0, s0 + addp v0.4s, v0.4s, v0.4s + fabs h1, h2 + fmlal v0.2s, v1.2h, v2.2h + psb csync + msr ERXPFGCTL_EL1, x0 + abs z31.h, p7/m, z31.h + sqdmlslbt z0.d, z1.s, z31.s + aesd z0.b, z0.b, z31.b + sm4e z0.s, z0.s, z0.s + rax1 z0.d, z0.d, z0.d + bdep z0.b, z1.b, z31.b + ldaprb w0, [x0] + mrs x0, RNDR + irg x0, x0 + mrs x2, SSBS + sb + cfp rctx, x0 + bfdot v2.2s, v3.4h, v4.4h + smmla v1.4s, v16.16b, v31.16b + fmmla z0.s, z1.s, z2.s + fmmla z0.d, z1.d, z2.d + tcommit + ld64b x0, [x13] + brb iall + pacia x0, x1 + cfinv + addha za0.s, p0/m, p0/m, z0.s + fmopa za0.d, p0/m, p0/m, z0.d, z0.d + addha za0.d, p0/m, p0/m, z0.d + bc.eq -0x1 + cpyfp [x0]!, [x1]!, x2! + mrs x0, PMCCNTR_EL0 + """ + def split(s): + return [x.strip() for x in s.strip().splitlines()] + + insts = target.GetInstructions(lldb.SBAddress(), raw_bytes) + + if self.TraceOn(): + print() + for i in insts: + print("Disassembled %s" % str(i)) + + if sys.version_info.major >= 3: + sio = StringIO() + insts.Print(sio) + self.assertEqual(split(assembly), split(sio.getvalue())) + + self.assertEqual(insts.GetSize(), len(split(assembly))) + + if sys.version_info.major >= 3: + for i,asm in enumerate(split(assembly)): + inst = insts.GetInstructionAtIndex(i) + sio = StringIO() + inst.Print(sio) + self.assertEqual(asm, sio.getvalue().strip()) diff --git a/lldb/test/API/python_api/disassemble-raw-data/aarch64-extensions/extensions.s b/lldb/test/API/python_api/disassemble-raw-data/aarch64-extensions/extensions.s new file mode 100644 --- /dev/null +++ b/lldb/test/API/python_api/disassemble-raw-data/aarch64-extensions/extensions.s @@ -0,0 +1,55 @@ +// This file is included in case we need to regenerate the test case. It is not used for +// the test directly because we can't be sure that the test compiler supports all of this. +// +// Extensions are in the same order as llvm/include/llvm/Support/AArch64TargetParser.def. +// Where the extension didn't add new instructions but did add sysregs, we use one of those. +// +// To regenerate the test, compile with: +// ./bin/clang -c ../llvm-project/lldb/test/API/python_api/disassemble-raw-data/aarch64-extensions/extensions.s -o /tmp/test.o -march=armv8-a+tme+memtag+crc+lse+rdm+sm4+sha3+aes+dotprod+fp16+fp16fml+sve+sve2+sve2-aes+sve2-sm4+sve2-sha3+sve2-bitperm+profile+rcpc+ssbs+sb+predres+bf16+mops+hbc+sme+sme-i64+sme-f64+flagm+pauth+brbe+ls64+f64mm+f32mm+i8mm+rng +// +// Then use llvm-objdump with equivalent features to get the encodings: +// ./bin/llvm-objdump -d /tmp/test.o --mattr=+tme,+mte,+crc,+lse,+rdm,+sm4,+sha3,+aes,+dotprod,+fullfp16,+fp16fml,+sve,+sve2,+sve2-aes,+sve2-sm4,+sve2-sha3,+sve2-bitperm,+spe,+rcpc,+ssbs,+sb,+predres,+bf16,+mops,+hbc,+sme,+sme-i64,+sme-f64,+flagm,+pauth,+brbe,+ls64,+f64mm,+f32mm,+i8mm,+rand +// (some names change because their backend feature name is different) + +crc32b w0, w0, w0 // CRC +ldaddab w0, w0, [sp] // LSE +sqrdmlah v0.4h, v1.4h, v2.4h // RDM +// CRYPTO enables a combination of other features +sm4e v0.4s, v0.4s // SM4 +bcax v0.16b, v0.16b, v0.16b, v0.16b // SHA3 +sha256h q0, q0, v0.4s // SHA256 +aesd v0.16b, v0.16b // AES +sdot v0.2s, v1.8b, v2.8b // DOTPROD +fcvt d0, s0 // FP +addp v0.4s, v0.4s, v0.4s // SIMD (neon) +fabs h1, h2 // FP16 +fmlal v0.2s, v1.2h, v2.2h // FP16FML +psb csync // PROFILE/SPE +msr erxpfgctl_el1, x0 // RAS +abs z31.h, p7/m, z31.h // SVE +sqdmlslbt z0.d, z1.s, z31.s // SVE2 +aesd z0.b, z0.b, z31.b // SVE2AES +sm4e z0.s, z0.s, z0.s // SVE2SM4 +rax1 z0.d, z0.d, z0.d // SVE2SHA3 +bdep z0.b, z1.b, z31.b // SVE2BITPERM +ldaprb w0, [x0, #0] // RCPC +mrs x0, rndr // RAND +irg x0, x0 // MTE +mrs x2, ssbs // SSBS +sb // SB +cfp rctx, x0 // PREDRES +bfdot v2.2s, v3.4h, v4.4h // BF16 +smmla v1.4s, v16.16b, v31.16b // I8MM +fmmla z0.s, z1.s, z2.s // F32MM +fmmla z0.d, z1.d, z2.d // F64MM +tcommit // TME +ld64b x0, [x13] // LS64 +brb iall // BRBE +pacia x0, x1 // PAUTH +cfinv // FLAGM +addha za0.s, p0/m, p0/m, z0.s // SME +fmopa za0.d, p0/m, p0/m, z0.d, z0.d // SMEF64 +addha za0.d, p0/m, p0/m, z0.d // SMEI64 +lbl: bc.eq lbl // HBC +cpyfp [x0]!, [x1]!, x2! // MOPS +mrs x0, pmccntr_el0 // PERFMON