Index: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td @@ -5759,6 +5759,12 @@ include "ARMInstrNEON.td" //===----------------------------------------------------------------------===// +// MVE Support +// + +include "ARMInstrMVE.td" + +//===----------------------------------------------------------------------===// // Assembler aliases // Index: llvm/trunk/lib/Target/ARM/ARMInstrMVE.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrMVE.td +++ llvm/trunk/lib/Target/ARM/ARMInstrMVE.td @@ -0,0 +1,130 @@ +//===-- ARMInstrMVE.td - MVE support for ARM ---------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the ARM MVE instruction set. +// +//===----------------------------------------------------------------------===// + +class MVE_MI_with_pred pattern> + : Thumb2I, + Requires<[HasV8_1MMainline, HasMVEInt]> { + let D = MVEDomain; + let DecoderNamespace = "MVE"; +} + +class t2MVEShift pattern=[]> + : MVE_MI_with_pred { + let Inst{31-20} = 0b111010100101; + let Inst{8} = 0b1; + +} + +class t2MVEShiftSingleReg pattern=[]> + : t2MVEShift { + bits<4> RdaDest; + + let Inst{19-16} = RdaDest{3-0}; +} + +class t2MVEShiftSRegImm op5_4, list pattern=[]> + : t2MVEShiftSingleReg { + bits<5> imm; + + let Inst{15} = 0b0; + let Inst{14-12} = imm{4-2}; + let Inst{11-8} = 0b1111; + let Inst{7-6} = imm{1-0}; + let Inst{5-4} = op5_4{1-0}; + let Inst{3-0} = 0b1111; +} + +def t2SQSHL : t2MVEShiftSRegImm<"sqshl", 0b11>; +def t2SRSHR : t2MVEShiftSRegImm<"srshr", 0b10>; +def t2UQSHL : t2MVEShiftSRegImm<"uqshl", 0b00>; +def t2URSHR : t2MVEShiftSRegImm<"urshr", 0b01>; + +class t2MVEShiftSRegReg op5_4, list pattern=[]> + : t2MVEShiftSingleReg { + bits<4> Rm; + + let Inst{15-12} = Rm{3-0}; + let Inst{11-8} = 0b1111; + let Inst{7-6} = 0b00; + let Inst{5-4} = op5_4{1-0}; + let Inst{3-0} = 0b1101; +} + +def t2SQRSHR : t2MVEShiftSRegReg<"sqrshr", 0b10>; +def t2UQRSHL : t2MVEShiftSRegReg<"uqrshl", 0b00>; + +class t2MVEShiftDoubleReg pattern=[]> + : t2MVEShift { + bits<4> RdaLo; + bits<4> RdaHi; + + let Inst{19-17} = RdaLo{3-1}; + let Inst{11-9} = RdaHi{3-1}; +} + +class t2MVEShiftDRegImm op5_4, bit op16, list pattern=[]> + : t2MVEShiftDoubleReg { + bits<5> imm; + + let Inst{16} = op16; + let Inst{15} = 0b0; + let Inst{14-12} = imm{4-2}; + let Inst{7-6} = imm{1-0}; + let Inst{5-4} = op5_4{1-0}; + let Inst{3-0} = 0b1111; +} + +class t2MVEShiftDRegReg pattern=[]> + : t2MVEShiftDoubleReg { + bits<4> Rm; + + let Inst{16} = op16; + let Inst{15-12} = Rm{3-0}; + let Inst{7-6} = 0b00; + let Inst{5} = op5; + let Inst{4} = 0b0; + let Inst{3-0} = 0b1101; + + // Custom decoder method because of the following overlapping encodings: + // ASRL and SQRSHR + // LSLL and UQRSHL + // SQRSHRL and SQRSHR + // UQRSHLL and UQRSHL + let DecoderMethod = "DecodeMVEOverlappingLongShift"; +} + +def t2ASRLr : t2MVEShiftDRegReg<"asrl", 0b1, 0b0>; +def t2ASRLi : t2MVEShiftDRegImm<"asrl", 0b10, ?>; +def t2LSLLr : t2MVEShiftDRegReg<"lsll", 0b0, 0b0>; +def t2LSLLi : t2MVEShiftDRegImm<"lsll", 0b00, ?>; +def t2LSRL : t2MVEShiftDRegImm<"lsrl", 0b01, ?>; + +def t2SQRSHRL : t2MVEShiftDRegReg<"sqrshrl", 0b1, 0b1>; +def t2SQSHLL : t2MVEShiftDRegImm<"sqshll", 0b11, 0b1>; +def t2SRSHRL : t2MVEShiftDRegImm<"srshrl", 0b10, 0b1>; + +def t2UQRSHLL : t2MVEShiftDRegReg<"uqrshll", 0b0, 0b1>; +def t2UQSHLL : t2MVEShiftDRegImm<"uqshll", 0b00, 0b1>; +def t2URSHRL : t2MVEShiftDRegImm<"urshrl", 0b01, 0b1>; Index: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td @@ -39,6 +39,16 @@ let DecoderMethod = "DecodeT2ShifterImmOperand"; } +def mve_shift_imm : AsmOperandClass { + let Name = "MVELongShift"; + let RenderMethod = "addImmOperands"; + let DiagnosticString = "operand must be an immediate in the range [1,32]"; +} +def long_shift : Operand { + let ParserMatchClass = mve_shift_imm; + let DecoderMethod = "DecodeLongShiftOperand"; +} + // Shifted operands. No register controlled shifts for Thumb2. // Note: We do not support rrx shifted operands yet. def t2_so_reg : Operand, // reg imm Index: llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp +++ llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp @@ -181,6 +181,13 @@ case tGPR_and_tcGPRRegClassID: case tcGPRRegClassID: case tGPRRegClassID: + case tGPREvenRegClassID: + case tGPROddRegClassID: + case tGPR_and_tGPREvenRegClassID: + case tGPR_and_tGPROddRegClassID: + case tGPREven_and_tcGPRRegClassID: + case tGPREven_and_tGPR_and_tcGPRRegClassID: + case tGPROdd_and_tcGPRRegClassID: return getRegBank(ARM::GPRRegBankID); case HPRRegClassID: case SPR_8RegClassID: Index: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td @@ -331,6 +331,20 @@ }]; } +def tGPROdd : RegisterClass<"ARM", [i32], 32, (add R1, R3, R5, R7, R9, R11)> { + let AltOrders = [(and tGPROdd, tGPR)]; + let AltOrderSelect = [{ + return MF.getSubtarget().isThumb1Only(); + }]; +} + +def tGPREven : RegisterClass<"ARM", [i32], 32, (add R0, R2, R4, R6, R8, R10, R12, LR)> { + let AltOrders = [(and tGPREven, tGPR)]; + let AltOrderSelect = [{ + return MF.getSubtarget().isThumb1Only(); + }]; +} + // Condition code registers. def CCR : RegisterClass<"ARM", [i32], 32, (add CPSR)> { let CopyCost = -1; // Don't allow copying of status registers. Index: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2048,6 +2048,15 @@ return (Value % Angle == Remainder && Value <= 270); } + bool isMVELongShift() const { + if (!isImm()) return false; + const MCConstantExpr *CE = dyn_cast(getImm()); + // Must be a constant. + if (!CE) return false; + uint64_t Value = CE->getValue(); + return Value >= 1 && Value <= 32; + } + bool isITCondCodeNoAL() const { if (!isITCondCode()) return false; auto CC = (ARMCC::CondCodes) getCondCode(); Index: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -146,6 +146,10 @@ uint64_t Address, const void *Decoder); static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); @@ -432,12 +436,18 @@ const void *Decoder); static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); template static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, + uint64_t Address, + const void *Decoder); #include "ARMGenDisassemblerTables.inc" static MCDisassembler *createARMDisassembler(const Target &T, @@ -801,6 +811,15 @@ uint32_t Insn32 = (Bytes[3] << 8) | (Bytes[2] << 0) | (Bytes[1] << 24) | (Bytes[0] << 16); + + Result = + decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + Check(Result, AddThumbPredicate(MI)); + return Result; + } + Result = decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI); if (Result != MCDisassembler::Fail) { @@ -5643,6 +5662,39 @@ return S; } +static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val, + uint64_t Address, + const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + + if (Val == 0) + Val = 32; + + Inst.addOperand(MCOperand::createImm(Val)); + + return S; +} + +static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder) { + if ((RegNo) + 1 > 11) + return MCDisassembler::Fail; + + unsigned Register = GPRDecoderTable[(RegNo) + 1]; + Inst.addOperand(MCOperand::createReg(Register)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder) { + if ((RegNo) > 14) + return MCDisassembler::Fail; + + unsigned Register = GPRDecoderTable[(RegNo)]; + Inst.addOperand(MCOperand::createReg(Register)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; @@ -5726,3 +5778,69 @@ return S; } + +static DecodeStatus DecodeMVEOverlappingLongShift( + MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + + unsigned RdaLo = fieldFromInstruction(Insn, 17, 3) << 1; + unsigned RdaHi = fieldFromInstruction(Insn, 9, 3) << 1; + unsigned Rm = fieldFromInstruction(Insn, 12, 4); + + if (RdaHi == 14) { + // This value of RdaHi (really indicating pc, because RdaHi has to + // be an odd-numbered register, so the low bit will be set by the + // decode function below) indicates that we must decode as SQRSHR + // or UQRSHL, which both have a single Rda register field with all + // four bits. + unsigned Rda = fieldFromInstruction(Insn, 16, 4); + + switch (Inst.getOpcode()) { + case ARM::t2ASRLr: + case ARM::t2SQRSHRL: + Inst.setOpcode(ARM::t2SQRSHR); + break; + case ARM::t2LSLLr: + case ARM::t2UQRSHLL: + Inst.setOpcode(ARM::t2UQRSHL); + break; + default: + llvm_unreachable("Unexpected starting opcode!"); + } + + // Rda as output parameter + if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder))) + return MCDisassembler::Fail; + + // Rda again as input parameter + if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder))) + return MCDisassembler::Fail; + + // Rm, the amount to shift by + if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) + return MCDisassembler::Fail; + + return S; + } + + // Otherwise, we decode as whichever opcode our caller has already + // put into Inst. Those all look the same: + + // RdaLo,RdaHi as output parameters + if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder))) + return MCDisassembler::Fail; + + // RdaLo,RdaHi again as input parameters + if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder))) + return MCDisassembler::Fail; + + // Rm, the amount to shift by + if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) + return MCDisassembler::Fail; + + return S; +} Index: llvm/trunk/test/MC/ARM/mve-scalar-shift.s =================================================================== --- llvm/trunk/test/MC/ARM/mve-scalar-shift.s +++ llvm/trunk/test/MC/ARM/mve-scalar-shift.s @@ -0,0 +1,156 @@ +# RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve -show-encoding < %s 2>%t \ +# RUN: | FileCheck --check-prefix=CHECK %s +# RUN: FileCheck --check-prefix=ERROR < %t %s +# RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding < %s 2>%t \ +# RUN: | FileCheck --check-prefix=CHECK %s +# RUN: FileCheck --check-prefix=ERROR < %t %s +# RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -show-encoding < %s 2>%t \ +# RUN: | FileCheck --check-prefix=CHECK-NOMVE %s +# RUN: FileCheck --check-prefix=ERROR-NOMVE < %t %s + +# CHECK: asrl r0, r1, #23 @ encoding: [0x50,0xea,0xef,0x51] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +asrl r0, r1, #23 + +# CHECK: asrl lr, r1, #27 @ encoding: [0x5e,0xea,0xef,0x61] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +asrl lr, r1, #27 + +# CHECK: it eq @ encoding: [0x08,0xbf] +# CHECK-NEXT: asrleq lr, r1, #27 @ encoding: [0x5e,0xea,0xef,0x61] +it eq +asrleq lr, r1, #27 + +# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid instruction +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: invalid instruction +asrl r3, r2, #33 + +# ERROR: [[@LINE+3]]:{{[0-9]+}}: {{error|note}}: operand must be an immediate in the range [1,32] +# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [r0, r12] or r14 +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction +asrl r0, r1, #33 + +# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction +asrl r0, r0, #32 + +# CHECK: asrl r0, r1, r4 @ encoding: [0x50,0xea,0x2d,0x41] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +asrl r0, r1, r4 + +# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction +asrl r0, r0, r4 + +# The assembler will reject the above shifts when MVE is not supported, +# so the previous valid instruction will be IT EQ, so we need to add +# a NOPEQ: +nopeq + +# CHECK: cinc lr, r2, lo @ encoding: [0x52,0xea,0x22,0x9e] +# CHECK-NOMVE: cinc lr, r2, lo @ encoding: [0x52,0xea,0x22,0x9e] +csinc lr, r2, r2, hs + +# CHECK: cinc lr, r7, pl @ encoding: [0x57,0xea,0x47,0x9e] +# CHECK-NOMVE: cinc lr, r7, pl @ encoding: [0x57,0xea,0x47,0x9e] +cinc lr, r7, pl + +# CHECK: cinv lr, r12, hs @ encoding: [0x5c,0xea,0x3c,0xae] +# CHECK-NOMVE: cinv lr, r12, hs @ encoding: [0x5c,0xea,0x3c,0xae] +cinv lr, r12, hs + +# CHECK: cneg lr, r10, hs @ encoding: [0x5a,0xea,0x3a,0xbe] +# CHECK-NOMVE: cneg lr, r10, hs @ encoding: [0x5a,0xea,0x3a,0xbe] +csneg lr, r10, r10, lo + +# CHECK: csel r9, r9, r11, vc @ encoding: [0x59,0xea,0x7b,0x89] +# CHECK-NOMVE: csel r9, r9, r11, vc @ encoding: [0x59,0xea,0x7b,0x89] +csel r9, r9, r11, vc + +# CHECK: cset lr, eq @ encoding: [0x5f,0xea,0x1f,0x9e] +# CHECK-NOMVE: cset lr, eq @ encoding: [0x5f,0xea,0x1f,0x9e] +cset lr, eq + +# CHECK: csetm lr, hs @ encoding: [0x5f,0xea,0x3f,0xae] +# CHECK-NOMVE: csetm lr, hs @ encoding: [0x5f,0xea,0x3f,0xae] +csetm lr, hs + +# CHECK: csinc lr, r10, r7, le @ encoding: [0x5a,0xea,0xd7,0x9e] +# CHECK-NOMVE: csinc lr, r10, r7, le @ encoding: [0x5a,0xea,0xd7,0x9e] +csinc lr, r10, r7, le + +# CHECK: csinv lr, r5, zr, hs @ encoding: [0x55,0xea,0x2f,0xae] +# CHECK-NOMVE: csinv lr, r5, zr, hs @ encoding: [0x55,0xea,0x2f,0xae] +csinv lr, r5, zr, hs + +# CHECK: cinv lr, r2, pl @ encoding: [0x52,0xea,0x42,0xae] +# CHECK-NOMVE: cinv lr, r2, pl @ encoding: [0x52,0xea,0x42,0xae] +csinv lr, r2, r2, mi + +# CHECK: csneg lr, r1, r11, vc @ encoding: [0x51,0xea,0x7b,0xbe] +# CHECK-NOMVE: csneg lr, r1, r11, vc @ encoding: [0x51,0xea,0x7b,0xbe] +csneg lr, r1, r11, vc + +# CHECK: lsll lr, r1, #11 @ encoding: [0x5e,0xea,0xcf,0x21] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +lsll lr, r1, #11 + +# CHECK: lsll lr, r1, r4 @ encoding: [0x5e,0xea,0x0d,0x41] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +lsll lr, r1, r4 + +# CHECK: lsrl lr, r1, #12 @ encoding: [0x5e,0xea,0x1f,0x31] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +lsrl lr, r1, #12 + +# CHECK: sqrshr lr, r12 @ encoding: [0x5e,0xea,0x2d,0xcf] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +sqrshr lr, r12 + +# CHECK: sqrshr r11, r12 @ encoding: [0x5b,0xea,0x2d,0xcf] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +sqrshr r11, r12 + +# CHECK: sqrshrl lr, r3, r8 @ encoding: [0x5f,0xea,0x2d,0x83] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +sqrshrl lr, r3, r8 + +# CHECK: sqshl lr, #17 @ encoding: [0x5e,0xea,0x7f,0x4f] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +sqshl lr, #17 + +# CHECK: sqshll lr, r11, #28 @ encoding: [0x5f,0xea,0x3f,0x7b] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +sqshll lr, r11, #28 + +# CHECK: srshr lr, #11 @ encoding: [0x5e,0xea,0xef,0x2f] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +srshr lr, #11 + +# CHECK: srshrl lr, r11, #23 @ encoding: [0x5f,0xea,0xef,0x5b] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +srshrl lr, r11, #23 + +# CHECK: uqrshl lr, r1 @ encoding: [0x5e,0xea,0x0d,0x1f] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +uqrshl lr, r1 + +# CHECK: uqrshll lr, r1, r4 @ encoding: [0x5f,0xea,0x0d,0x41] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +uqrshll lr, r1, r4 + +# CHECK: uqshl r0, #1 @ encoding: [0x50,0xea,0x4f,0x0f] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +uqshl r0, #1 + +# CHECK: uqshll lr, r7, #7 @ encoding: [0x5f,0xea,0xcf,0x17] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +uqshll lr, r7, #7 + +# CHECK: urshr r0, #10 @ encoding: [0x50,0xea,0x9f,0x2f] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +urshr r0, #10 + +# CHECK: urshrl r0, r9, #29 @ encoding: [0x51,0xea,0x5f,0x79] +# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve +urshrl r0, r9, #29 Index: llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt +++ llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt @@ -0,0 +1,83 @@ +# RUN: llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding %s | FileCheck %s +# RUN: not llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -show-encoding %s &> %t +# RUN: FileCheck --check-prefix=CHECK-NOMVE < %t %s + +[0x50 0xea 0xef 0x51] +# CHECK: asrl r0, r1, #23 @ encoding: [0x50,0xea,0xef,0x51] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction + +[0x5e 0xea 0xef 0x61] +# CHECK: asrl lr, r1, #27 @ encoding: [0x5e,0xea,0xef,0x61] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x50 0xea 0x2d 0x41] +# CHECK: asrl r0, r1, r4 @ encoding: [0x50,0xea,0x2d,0x41] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5e 0xea 0xcf 0x21] +# CHECK: lsll lr, r1, #11 @ encoding: [0x5e,0xea,0xcf,0x21] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5e 0xea 0x0d 0x41] +# CHECK: lsll lr, r1, r4 @ encoding: [0x5e,0xea,0x0d,0x41] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5e 0xea 0x1f 0x31] +# CHECK: lsrl lr, r1, #12 @ encoding: [0x5e,0xea,0x1f,0x31] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5f 0xea 0x2d 0x83] +# CHECK: sqrshrl lr, r3, r8 @ encoding: [0x5f,0xea,0x2d,0x83] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5e 0xea 0x7f 0x4f] +# CHECK: sqshl lr, #17 @ encoding: [0x5e,0xea,0x7f,0x4f] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5f 0xea 0x3f 0x7b] +# CHECK: sqshll lr, r11, #28 @ encoding: [0x5f,0xea,0x3f,0x7b] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5e 0xea 0xef 0x2f] +# CHECK: srshr lr, #11 @ encoding: [0x5e,0xea,0xef,0x2f] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5f 0xea 0xef 0x5b] +# CHECK: srshrl lr, r11, #23 @ encoding: [0x5f,0xea,0xef,0x5b] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5e 0xea 0x2d 0xcf] +# CHECK: sqrshr lr, r12 @ encoding: [0x5e,0xea,0x2d,0xcf] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding + +[0x5b 0xea 0x2d 0xcf] +# CHECK: sqrshr r11, r12 @ encoding: [0x5b,0xea,0x2d,0xcf] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding + +[0x5e 0xea 0x0d 0xcf] +# CHECK: uqrshl lr, r12 @ encoding: [0x5e,0xea,0x0d,0xcf] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding + +[0x5b 0xea 0x0d 0xcf] +# CHECK: uqrshl r11, r12 @ encoding: [0x5b,0xea,0x0d,0xcf] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding + +[0x5f 0xea 0x0d 0x41] +# CHECK: uqrshll lr, r1, r4 @ encoding: [0x5f,0xea,0x0d,0x41] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x50 0xea 0x4f 0x0f] +# CHECK: uqshl r0, #1 @ encoding: [0x50,0xea,0x4f,0x0f] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5f 0xea 0xcf 0x17] +# CHECK: uqshll lr, r7, #7 @ encoding: [0x5f,0xea,0xcf,0x17] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x50 0xea 0x9f 0x2f] +# CHECK: urshr r0, #10 @ encoding: [0x50,0xea,0x9f,0x2f] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x51 0xea 0x5f 0x79] +# CHECK: urshrl r0, r9, #29 @ encoding: [0x51,0xea,0x5f,0x79] +# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding