From d87c77c0e8fdc86283ea3ccc00dad1e5e911093f Mon Sep 17 00:00:00 2001 From: Bradley Smith Date: Tue, 14 Apr 2015 15:07:26 +0000 Subject: [PATCH] [AArch64] Allow non-standard INS/DUP encodings The ARMv8 ARMARM states that for these instructions in A64 state: "Unspecified bits in "imm5" are ignored but should be set to zero by an assembler.", (imm4 for INS). Make the disassembler accept any encoding with these ignored bits set to 1. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234896 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64InstrFormats.td | 6 +-- lib/Target/AArch64/AArch64InstrInfo.td | 14 +++---- .../MC/Disassembler/AArch64/arm64-advsimd.txt | 37 +++++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/Target/AArch64/AArch64InstrFormats.td b/lib/Target/AArch64/AArch64InstrFormats.td index 0e457329f73..2873898b09e 100644 --- a/lib/Target/AArch64/AArch64InstrFormats.td +++ b/lib/Target/AArch64/AArch64InstrFormats.td @@ -5922,7 +5922,7 @@ multiclass SIMDIns { let Inst{20-18} = idx; let Inst{17-16} = 0b10; let Inst{14-12} = idx2; - let Inst{11} = 0; + let Inst{11} = {?}; } def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { bits<2> idx; @@ -5930,7 +5930,7 @@ multiclass SIMDIns { let Inst{20-19} = idx; let Inst{18-16} = 0b100; let Inst{14-13} = idx2; - let Inst{12-11} = 0; + let Inst{12-11} = {?,?}; } def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { bits<1> idx; @@ -5938,7 +5938,7 @@ multiclass SIMDIns { let Inst{20} = idx; let Inst{19-16} = 0b1000; let Inst{14} = idx2; - let Inst{13-11} = 0; + let Inst{13-11} = {?,?,?}; } // For all forms of the INS instruction, the "mov" mnemonic is the diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td index 9761163781d..614f29cd5ef 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.td +++ b/lib/Target/AArch64/AArch64InstrInfo.td @@ -3496,13 +3496,13 @@ def : Pat<(f64 (int_aarch64_neon_fminv (v2f64 V128:$Rn))), // AdvSIMD INS/DUP instructions //---------------------------------------------------------------------------- -def DUPv8i8gpr : SIMDDupFromMain<0, 0b00001, ".8b", v8i8, V64, GPR32>; -def DUPv16i8gpr : SIMDDupFromMain<1, 0b00001, ".16b", v16i8, V128, GPR32>; -def DUPv4i16gpr : SIMDDupFromMain<0, 0b00010, ".4h", v4i16, V64, GPR32>; -def DUPv8i16gpr : SIMDDupFromMain<1, 0b00010, ".8h", v8i16, V128, GPR32>; -def DUPv2i32gpr : SIMDDupFromMain<0, 0b00100, ".2s", v2i32, V64, GPR32>; -def DUPv4i32gpr : SIMDDupFromMain<1, 0b00100, ".4s", v4i32, V128, GPR32>; -def DUPv2i64gpr : SIMDDupFromMain<1, 0b01000, ".2d", v2i64, V128, GPR64>; +def DUPv8i8gpr : SIMDDupFromMain<0, {?,?,?,?,1}, ".8b", v8i8, V64, GPR32>; +def DUPv16i8gpr : SIMDDupFromMain<1, {?,?,?,?,1}, ".16b", v16i8, V128, GPR32>; +def DUPv4i16gpr : SIMDDupFromMain<0, {?,?,?,1,0}, ".4h", v4i16, V64, GPR32>; +def DUPv8i16gpr : SIMDDupFromMain<1, {?,?,?,1,0}, ".8h", v8i16, V128, GPR32>; +def DUPv2i32gpr : SIMDDupFromMain<0, {?,?,1,0,0}, ".2s", v2i32, V64, GPR32>; +def DUPv4i32gpr : SIMDDupFromMain<1, {?,?,1,0,0}, ".4s", v4i32, V128, GPR32>; +def DUPv2i64gpr : SIMDDupFromMain<1, {?,1,0,0,0}, ".2d", v2i64, V128, GPR64>; def DUPv2i64lane : SIMDDup64FromElement; def DUPv2i32lane : SIMDDup32FromElement<0, ".2s", v2i32, V64>; diff --git a/test/MC/Disassembler/AArch64/arm64-advsimd.txt b/test/MC/Disassembler/AArch64/arm64-advsimd.txt index cceee672dfd..ef125c8e32f 100644 --- a/test/MC/Disassembler/AArch64/arm64-advsimd.txt +++ b/test/MC/Disassembler/AArch64/arm64-advsimd.txt @@ -169,6 +169,43 @@ # CHECK: ins.h v2[7], v15[3] # CHECK: ins.b v2[10], v15[5] +# INS/DUP (non-standard) +0x60 0x0c 0x08 0x4e +0x60 0x0c 0x0c 0x4e +0x60 0x0c 0x0c 0x0e +0x60 0x0c 0x0e 0x4e +0x60 0x0c 0x0e 0x0e +0x60 0x0c 0x0f 0x4e +0x60 0x0c 0x0f 0x0e + +# CHECK: dup.2d v0, x3 +# CHECK: dup.4s v0, w3 +# CHECK: dup.2s v0, w3 +# CHECK: dup.8h v0, w3 +# CHECK: dup.4h v0, w3 +# CHECK: dup.16b v0, w3 +# CHECK: dup.8b v0, w3 + +0xe2 0x75 0x18 0x6e +0xe2 0x35 0x0c 0x6e +0xe2 0x15 0x06 0x6e +0xe2 0x0d 0x03 0x6e + +0xe2 0x05 0x18 0x6e +0xe2 0x55 0x1c 0x6e +0xe2 0x35 0x1e 0x6e +0xe2 0x2d 0x15 0x6e + +# CHECK: ins.d v2[1], v15[1] +# CHECK: ins.s v2[1], v15[1] +# CHECK: ins.h v2[1], v15[1] +# CHECK: ins.b v2[1], v15[1] + +# CHECK: ins.d v2[1], v15[0] +# CHECK: ins.s v2[3], v15[2] +# CHECK: ins.h v2[7], v15[3] +# CHECK: ins.b v2[10], v15[5] + 0x00 0x1c 0x20 0x0e 0x00 0x1c 0x20 0x4e