From de29a52940101cd162cc9a53cfd3d09d60547e6f Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Fri, 15 Apr 2011 00:10:45 +0000 Subject: [PATCH] The ARM disassembler did not handle the alignment correctly for VLD*DUP* instructions (single element or n-element structure to all lanes). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129550 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../ARM/Disassembler/ARMDisassemblerCore.cpp | 27 +++++++++++++++++++ .../ARM/invalid-VLD1DUPq8_UPD-arm.txt | 10 +++++++ test/MC/Disassembler/ARM/neon-tests.txt | 6 +++++ 3 files changed, 43 insertions(+) create mode 100644 test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 4ecb8be012d..b7a9a8b5250 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -2657,6 +2657,33 @@ static bool DisassembleNLdSt(MCInst &MI, unsigned Opcode, uint32_t insn, // == 32 && Inst{6} == 1 --> DblSpaced = true if (Name.endswith("32") || Name.endswith("32_UPD")) DblSpaced = slice(insn, 6, 6) == 1; + } else if (Name.find("DUP") != std::string::npos) { + // Single element (or structure) to all lanes. + // Inst{9-8} encodes the number of element(s) in the structure, with: + // 0b00 (VLD1DUP) (for this, a bit makes sense only for data size 16 and 32. + // 0b01 (VLD2DUP) + // 0b10 (VLD3DUP) (for this, a bit must be encoded as 0) + // 0b11 (VLD4DUP) + // + // Inst{7-6} encodes the data size, with: + // 0b00 => 8, 0b01 => 16, 0b10 => 32 + // + // Inst{4} (the a bit) encodes the align action (0: standard alignment) + unsigned elem = slice(insn, 9, 8) + 1; + unsigned a = slice(insn, 4, 4); + if (elem != 3) { + // 0b11 is not a valid encoding for Inst{7-6}. + if (slice(insn, 7, 6) == 3) + return false; + unsigned data_size = 8 << slice(insn, 7, 6); + // For VLD1DUP, a bit makes sense only for data size of 16 and 32. + if (a && data_size == 8) + return false; + + // Now we can calculate the alignment! + if (a) + alignment = elem * data_size; + } } else { // Multiple n-element structures with type encoded as Inst{11-8}. // See, for example, A8.6.316 VLD4 (multiple 4-element structures). diff --git a/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt b/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt new file mode 100644 index 00000000000..56d9ad704a0 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt @@ -0,0 +1,10 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=737 Name=VLD1DUPq8_UPD Format=ARM_FORMAT_NLdSt(30) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 1: 1| 0: 1: 0: 0| 1: 0: 1: 0| 0: 0: 0: 0| 0: 0: 1: 1| 1: 1: 0: 0| 0: 0: 1: 1| 1: 1: 0: 1| +# ------------------------------------------------------------------------------------------------- +# +# 'a' == 1 and data_size == 8 is invalid +0x3d 0x3c 0xa0 0xf4 diff --git a/test/MC/Disassembler/ARM/neon-tests.txt b/test/MC/Disassembler/ARM/neon-tests.txt index 964459f130a..cfb5949284c 100644 --- a/test/MC/Disassembler/ARM/neon-tests.txt +++ b/test/MC/Disassembler/ARM/neon-tests.txt @@ -21,6 +21,12 @@ # CHECK: vld4.8 {d4, d6, d8, d10}, [r2] 0x0f 0x41 0x22 0xf4 +# CHECK: vld1.32 {d3[], d4[]}, [r0, :32]! +0xbd 0x3c 0xa0 0xf4 + +# CHECK: vld4.16 {d3[], d4[], d5[], d6[]}, [r0, :64]! +0x7d 0x3f 0xa0 0xf4 + # CHECK: vmov d0, d15 0x1f 0x01 0x2f 0xf2 -- 2.34.1