Index: llvm/trunk/lib/Target/ARM/ARMInstrMVE.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrMVE.td +++ llvm/trunk/lib/Target/ARM/ARMInstrMVE.td @@ -62,6 +62,8 @@ let RenderMethod = "addITCondCodeOperands"; let PredicateMethod = "isITCondCodeRestrictedI"; let ParserMethod = "parseITCondCode"; + let DiagnosticString = "condition code for sign-independent integer "# + "comparison must be EQ or NE"; } // VPT/VCMP restricted predicate for signed types @@ -70,6 +72,8 @@ let RenderMethod = "addITCondCodeOperands"; let PredicateMethod = "isITCondCodeRestrictedS"; let ParserMethod = "parseITCondCode"; + let DiagnosticString = "condition code for signed integer "# + "comparison must be EQ, NE, LT, GT, LE or GE"; } // VPT/VCMP restricted predicate for unsigned types @@ -78,6 +82,8 @@ let RenderMethod = "addITCondCodeOperands"; let PredicateMethod = "isITCondCodeRestrictedU"; let ParserMethod = "parseITCondCode"; + let DiagnosticString = "condition code for unsigned integer "# + "comparison must be EQ, NE, HS or HI"; } // VPT/VCMP restricted predicate for floating point @@ -86,30 +92,34 @@ let RenderMethod = "addITCondCodeOperands"; let PredicateMethod = "isITCondCodeRestrictedFP"; let ParserMethod = "parseITCondCode"; + let DiagnosticString = "condition code for floating-point "# + "comparison must be EQ, NE, LT, GT, LE or GE"; } -def pred_basic_i : Operand { +class VCMPPredicateOperand : Operand; + +def pred_basic_i : VCMPPredicateOperand { let PrintMethod = "printMandatoryRestrictedPredicateOperand"; let ParserMatchClass = pred_restricted_i_asmoperand; let DecoderMethod = "DecodeRestrictedIPredicateOperand"; let EncoderMethod = "getRestrictedCondCodeOpValue"; } -def pred_basic_u : Operand { +def pred_basic_u : VCMPPredicateOperand { let PrintMethod = "printMandatoryRestrictedPredicateOperand"; let ParserMatchClass = pred_restricted_u_asmoperand; let DecoderMethod = "DecodeRestrictedUPredicateOperand"; let EncoderMethod = "getRestrictedCondCodeOpValue"; } -def pred_basic_s : Operand { +def pred_basic_s : VCMPPredicateOperand { let PrintMethod = "printMandatoryRestrictedPredicateOperand"; let ParserMatchClass = pred_restricted_s_asmoperand; let DecoderMethod = "DecodeRestrictedSPredicateOperand"; let EncoderMethod = "getRestrictedCondCodeOpValue"; } -def pred_basic_fp : Operand { +def pred_basic_fp : VCMPPredicateOperand { let PrintMethod = "printMandatoryRestrictedPredicateOperand"; let ParserMatchClass = pred_restricted_fp_asmoperand; let DecoderMethod = "DecodeRestrictedFPPredicateOperand"; @@ -2253,6 +2263,147 @@ // end of MVE Floating Point instructions +// start of MVE compares + +class MVE_VCMPqq bits_21_20, + VCMPPredicateOperand predtype, list pattern=[]> + : MVE_p<(outs VCCR:$P0), (ins MQPR:$Qn, MQPR:$Qm, predtype:$fc), + NoItinerary, "vcmp", suffix, "$fc, $Qn, $Qm", vpred_n, "", pattern> { + // Base class for comparing two vector registers + bits<3> fc; + bits<4> Qn; + bits<4> Qm; + + let Inst{28} = bit_28; + let Inst{25-22} = 0b1000; + let Inst{21-20} = bits_21_20; + let Inst{19-17} = Qn{2-0}; + let Inst{16-13} = 0b1000; + let Inst{12} = fc{2}; + let Inst{11-8} = 0b1111; + let Inst{7} = fc{0}; + let Inst{6} = 0b0; + let Inst{5} = Qm{3}; + let Inst{4} = 0b0; + let Inst{3-1} = Qm{2-0}; + let Inst{0} = fc{1}; + + let Constraints = ""; + + // We need a custom decoder method for these instructions because of + // the output VCCR operand, which isn't encoded in the instruction + // bits anywhere (there is only one choice for it) but has to be + // included in the MC operands so that codegen will be able to track + // its data flow between instructions, spill/reload it when + // necessary, etc. There seems to be no way to get the Tablegen + // decoder to emit an operand that isn't affected by any instruction + // bit. + let DecoderMethod = "DecodeMVEVCMP"; +} + +class MVE_VCMPqqf + : MVE_VCMPqq { + let Predicates = [HasMVEFloat]; +} + +class MVE_VCMPqqi size> + : MVE_VCMPqq { + let Inst{12} = 0b0; + let Inst{0} = 0b0; +} + +class MVE_VCMPqqu size> + : MVE_VCMPqq { + let Inst{12} = 0b0; + let Inst{0} = 0b1; +} + +class MVE_VCMPqqs size> + : MVE_VCMPqq { + let Inst{12} = 0b1; +} + +def MVE_VCMPf32 : MVE_VCMPqqf<"f32", 0b0>; +def MVE_VCMPf16 : MVE_VCMPqqf<"f16", 0b1>; + +def MVE_VCMPi8 : MVE_VCMPqqi<"i8", 0b00>; +def MVE_VCMPi16 : MVE_VCMPqqi<"i16", 0b01>; +def MVE_VCMPi32 : MVE_VCMPqqi<"i32", 0b10>; + +def MVE_VCMPu8 : MVE_VCMPqqu<"u8", 0b00>; +def MVE_VCMPu16 : MVE_VCMPqqu<"u16", 0b01>; +def MVE_VCMPu32 : MVE_VCMPqqu<"u32", 0b10>; + +def MVE_VCMPs8 : MVE_VCMPqqs<"s8", 0b00>; +def MVE_VCMPs16 : MVE_VCMPqqs<"s16", 0b01>; +def MVE_VCMPs32 : MVE_VCMPqqs<"s32", 0b10>; + +class MVE_VCMPqr bits_21_20, + VCMPPredicateOperand predtype, list pattern=[]> + : MVE_p<(outs VCCR:$P0), (ins MQPR:$Qn, GPRwithZR:$Rm, predtype:$fc), + NoItinerary, "vcmp", suffix, "$fc, $Qn, $Rm", vpred_n, "", pattern> { + // Base class for comparing a vector register with a scalar + bits<3> fc; + bits<4> Qn; + bits<4> Rm; + + let Inst{28} = bit_28; + let Inst{25-22} = 0b1000; + let Inst{21-20} = bits_21_20; + let Inst{19-17} = Qn{2-0}; + let Inst{16-13} = 0b1000; + let Inst{12} = fc{2}; + let Inst{11-8} = 0b1111; + let Inst{7} = fc{0}; + let Inst{6} = 0b1; + let Inst{5} = fc{1}; + let Inst{4} = 0b0; + let Inst{3-0} = Rm{3-0}; + + let Constraints = ""; + // Custom decoder method, for the same reason as MVE_VCMPqq + let DecoderMethod = "DecodeMVEVCMP"; +} + +class MVE_VCMPqrf + : MVE_VCMPqr { + let Predicates = [HasMVEFloat]; +} + +class MVE_VCMPqri size> + : MVE_VCMPqr { + let Inst{12} = 0b0; + let Inst{5} = 0b0; +} + +class MVE_VCMPqru size> + : MVE_VCMPqr { + let Inst{12} = 0b0; + let Inst{5} = 0b1; +} + +class MVE_VCMPqrs size> + : MVE_VCMPqr { + let Inst{12} = 0b1; +} + +def MVE_VCMPf32r : MVE_VCMPqrf<"f32", 0b0>; +def MVE_VCMPf16r : MVE_VCMPqrf<"f16", 0b1>; + +def MVE_VCMPi8r : MVE_VCMPqri<"i8", 0b00>; +def MVE_VCMPi16r : MVE_VCMPqri<"i16", 0b01>; +def MVE_VCMPi32r : MVE_VCMPqri<"i32", 0b10>; + +def MVE_VCMPu8r : MVE_VCMPqru<"u8", 0b00>; +def MVE_VCMPu16r : MVE_VCMPqru<"u16", 0b01>; +def MVE_VCMPu32r : MVE_VCMPqru<"u32", 0b10>; + +def MVE_VCMPs8r : MVE_VCMPqrs<"s8", 0b00>; +def MVE_VCMPs16r : MVE_VCMPqrs<"s16", 0b01>; +def MVE_VCMPs32r : MVE_VCMPqrs<"s32", 0b10>; + +// end of MVE compares + class MVE_VPT size, dag iops, string asm, list pattern=[]> : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> { bits<3> fc; 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 @@ -6568,6 +6568,7 @@ // scalar predication operand we do not add the vector one and leave until // now to fix it up. if (CanAcceptVPTPredicationCode && Mnemonic != "vmov" && + !Mnemonic.startswith("vcmp") && !(Mnemonic.startswith("vcvt") && Mnemonic != "vcvta" && Mnemonic != "vcvtn" && Mnemonic != "vcvtp" && Mnemonic != "vcvtm")) { SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + @@ -6683,12 +6684,12 @@ Operands.insert(Operands.begin(), ARMOperand::CreateToken(StringRef("vcvtn"), MLoc)); } - // For vmov instructions, as mentioned earlier, we did not add the vector + // For vmov and vcmp, as mentioned earlier, we did not add the vector // predication code, since these may contain operands that require // special parsing. So now we have to see if they require vector // predication and replace the scalar one with the vector predication // operand if that is the case. - else if (Mnemonic == "vmov" || + else if (Mnemonic == "vmov" || Mnemonic.startswith("vcmp") || (Mnemonic.startswith("vcvt") && !Mnemonic.startswith("vcvta") && !Mnemonic.startswith("vcvtn") && !Mnemonic.startswith("vcvtp") && !Mnemonic.startswith("vcvtm"))) { 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 @@ -509,6 +509,11 @@ const void *Decoder); static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +typedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); +template +static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -6183,3 +6188,41 @@ return S; } + +template +static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address, + const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + Inst.addOperand(MCOperand::createReg(ARM::VPR)); + unsigned Qn = fieldFromInstruction(Insn, 17, 3); + if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder))) + return MCDisassembler::Fail; + + unsigned fc; + + if (scalar) { + fc = fieldFromInstruction(Insn, 12, 1) << 2 | + fieldFromInstruction(Insn, 7, 1) | + fieldFromInstruction(Insn, 5, 1) << 1; + unsigned Rm = fieldFromInstruction(Insn, 0, 4); + if (!Check(S, DecodeGPRwithZRRegisterClass(Inst, Rm, Address, Decoder))) + return MCDisassembler::Fail; + } else { + fc = fieldFromInstruction(Insn, 12, 1) << 2 | + fieldFromInstruction(Insn, 7, 1) | + fieldFromInstruction(Insn, 0, 1) << 1; + unsigned Qm = fieldFromInstruction(Insn, 5, 1) << 4 | + fieldFromInstruction(Insn, 1, 3); + if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) + return MCDisassembler::Fail; + } + + if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder))) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::createImm(ARMVCC::None)); + Inst.addOperand(MCOperand::createReg(0)); + Inst.addOperand(MCOperand::createImm(0)); + + return S; +} Index: llvm/trunk/test/MC/ARM/mve-vcmp.s =================================================================== --- llvm/trunk/test/MC/ARM/mve-vcmp.s +++ llvm/trunk/test/MC/ARM/mve-vcmp.s @@ -0,0 +1,299 @@ +# RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve -show-encoding < %s 2>%t \ +# RUN: | FileCheck --check-prefix=CHECK-NOFP %s +# RUN: FileCheck --check-prefix=ERROR-NOFP < %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 + +# CHECK: vcmp.f16 eq, q0, q4 @ encoding: [0x31,0xfe,0x08,0x0f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 eq, q0, q4 @ encoding: [0x31,0xfe,0x08,0x0f] +vcmp.f16 eq, q0, q4 + +# CHECK: vcmp.f16 ne, q2, q7 @ encoding: [0x35,0xfe,0x8e,0x0f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 ne, q2, q7 @ encoding: [0x35,0xfe,0x8e,0x0f] +vcmp.f16 ne, q2, q7 + +# CHECK: vcmp.f16 ge, q0, q0 @ encoding: [0x31,0xfe,0x00,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 ge, q0, q0 @ encoding: [0x31,0xfe,0x00,0x1f] +vcmp.f16 ge, q0, q0 + +# CHECK: vcmp.f16 lt, q0, q1 @ encoding: [0x31,0xfe,0x82,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 lt, q0, q1 @ encoding: [0x31,0xfe,0x82,0x1f] +vcmp.f16 lt, q0, q1 + +# CHECK: vcmp.f16 gt, q1, q4 @ encoding: [0x33,0xfe,0x09,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 gt, q1, q4 @ encoding: [0x33,0xfe,0x09,0x1f] +vcmp.f16 gt, q1, q4 + +# CHECK: vcmp.f16 le, q2, q6 @ encoding: [0x35,0xfe,0x8d,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 le, q2, q6 @ encoding: [0x35,0xfe,0x8d,0x1f] +vcmp.f16 le, q2, q6 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for floating-point comparison must be EQ, NE, LT, GT, LE or GE +vcmp.f16 hi, q2, q6 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for floating-point comparison must be EQ, NE, LT, GT, LE or GE +vcmp.f16 hs, q2, q6 + +# CHECK: vcmp.f32 eq, q2, q5 @ encoding: [0x35,0xee,0x0a,0x0f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f32 eq, q2, q5 @ encoding: [0x35,0xee,0x0a,0x0f] +vcmp.f32 eq, q2, q5 + +# CHECK: vcmp.f32 ne, q3, q4 @ encoding: [0x37,0xee,0x88,0x0f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f32 ne, q3, q4 @ encoding: [0x37,0xee,0x88,0x0f] +vcmp.f32 ne, q3, q4 + +# CHECK: vcmp.f32 ge, q0, q7 @ encoding: [0x31,0xee,0x0e,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f32 ge, q0, q7 @ encoding: [0x31,0xee,0x0e,0x1f] +vcmp.f32 ge, q0, q7 + +# CHECK: vcmp.f32 lt, q5, q2 @ encoding: [0x3b,0xee,0x84,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f32 lt, q5, q2 @ encoding: [0x3b,0xee,0x84,0x1f] +vcmp.f32 lt, q5, q2 + +# CHECK: vcmp.f32 gt, q2, q7 @ encoding: [0x35,0xee,0x0f,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f32 gt, q2, q7 @ encoding: [0x35,0xee,0x0f,0x1f] +vcmp.f32 gt, q2, q7 + +# CHECK: vcmp.f32 le, q2, q4 @ encoding: [0x35,0xee,0x89,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f32 le, q2, q4 @ encoding: [0x35,0xee,0x89,0x1f] +vcmp.f32 le, q2, q4 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for floating-point comparison must be EQ, NE, LT, GT, LE or GE +vcmp.f32 hi, q2, q6 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for floating-point comparison must be EQ, NE, LT, GT, LE or GE +vcmp.f32 hs, q2, q6 + +# CHECK: vcmp.i8 eq, q4, q6 @ encoding: [0x09,0xfe,0x0c,0x0f] +# CHECK-NOFP: vcmp.i8 eq, q4, q6 @ encoding: [0x09,0xfe,0x0c,0x0f] +vcmp.i8 eq, q4, q6 + +# CHECK: vcmp.i8 ne, q2, q2 @ encoding: [0x05,0xfe,0x84,0x0f] +# CHECK-NOFP: vcmp.i8 ne, q2, q2 @ encoding: [0x05,0xfe,0x84,0x0f] +vcmp.i8 ne, q2, q2 + +# ERROR: [[@LINE+1]]:9: {{error|note}}: condition code for sign-independent integer comparison must be EQ or NE +vcmp.i8 hs, q2, q6 + +# ERROR: [[@LINE+1]]:9: {{error|note}}: condition code for sign-independent integer comparison must be EQ or NE +vcmp.i8 le, q2, q6 + +# CHECK: vcmp.i8 eq, q4, q6 @ encoding: [0x09,0xfe,0x0c,0x0f] +# CHECK-NOFP: vcmp.i8 eq, q4, q6 @ encoding: [0x09,0xfe,0x0c,0x0f] +vcmp.s8 eq, q4, q6 + +# CHECK: vcmp.i8 ne, q2, q2 @ encoding: [0x05,0xfe,0x84,0x0f] +# CHECK-NOFP: vcmp.i8 ne, q2, q2 @ encoding: [0x05,0xfe,0x84,0x0f] +vcmp.s8 ne, q2, q2 + +# CHECK: vcmp.i8 eq, q4, q6 @ encoding: [0x09,0xfe,0x0c,0x0f] +# CHECK-NOFP: vcmp.i8 eq, q4, q6 @ encoding: [0x09,0xfe,0x0c,0x0f] +vcmp.u8 eq, q4, q6 + +# CHECK: vcmp.i8 ne, q2, q2 @ encoding: [0x05,0xfe,0x84,0x0f] +# CHECK-NOFP: vcmp.i8 ne, q2, q2 @ encoding: [0x05,0xfe,0x84,0x0f] +vcmp.u8 ne, q2, q2 + +# CHECK: vcmp.s8 ge, q0, q0 @ encoding: [0x01,0xfe,0x00,0x1f] +# CHECK-NOFP: vcmp.s8 ge, q0, q0 @ encoding: [0x01,0xfe,0x00,0x1f] +vcmp.s8 ge, q0, q0 + +# CHECK: vcmp.s8 lt, q2, q7 @ encoding: [0x05,0xfe,0x8e,0x1f] +# CHECK-NOFP: vcmp.s8 lt, q2, q7 @ encoding: [0x05,0xfe,0x8e,0x1f] +vcmp.s8 lt, q2, q7 + +# CHECK: vcmp.s8 gt, q4, q3 @ encoding: [0x09,0xfe,0x07,0x1f] +# CHECK-NOFP: vcmp.s8 gt, q4, q3 @ encoding: [0x09,0xfe,0x07,0x1f] +vcmp.s8 gt, q4, q3 + +# CHECK: vcmp.s8 le, q7, q3 @ encoding: [0x0f,0xfe,0x87,0x1f] +# CHECK-NOFP: vcmp.s8 le, q7, q3 @ encoding: [0x0f,0xfe,0x87,0x1f] +vcmp.s8 le, q7, q3 + +# ERROR: [[@LINE+1]]:9: {{error|note}}: condition code for signed integer comparison must be EQ, NE, LT, GT, LE or GE +vcmp.s8 hs, q2, q6 + +# CHECK: vcmp.u8 hi, q1, q4 @ encoding: [0x03,0xfe,0x89,0x0f] +# CHECK-NOFP: vcmp.u8 hi, q1, q4 @ encoding: [0x03,0xfe,0x89,0x0f] +vcmp.u8 hi, q1, q4 + +# CHECK: vcmp.u8 cs, q1, q4 @ encoding: [0x03,0xfe,0x09,0x0f] +# CHECK-NOFP: vcmp.u8 cs, q1, q4 @ encoding: [0x03,0xfe,0x09,0x0f] +vcmp.u8 cs, q1, q4 + +# ERROR: [[@LINE+1]]:9: {{error|note}}: condition code for unsigned integer comparison must be EQ, NE, HS or HI +vcmp.u8 gt, q2, q6 + +# ERROR: [[@LINE+1]]:9: {{error|note}}: condition code for unsigned integer comparison must be EQ, NE, HS or HI +vcmp.u8 lo, q2, q6 + +# CHECK: vcmp.i16 eq, q4, q7 @ encoding: [0x19,0xfe,0x0e,0x0f] +# CHECK-NOFP: vcmp.i16 eq, q4, q7 @ encoding: [0x19,0xfe,0x0e,0x0f] +vcmp.i16 eq, q4, q7 + +# CHECK: vcmp.i16 ne, q2, q1 @ encoding: [0x15,0xfe,0x82,0x0f] +# CHECK-NOFP: vcmp.i16 ne, q2, q1 @ encoding: [0x15,0xfe,0x82,0x0f] +vcmp.i16 ne, q2, q1 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for sign-independent integer comparison must be EQ or NE +vcmp.i16 hi, q2, q6 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for sign-independent integer comparison must be EQ or NE +vcmp.i16 lt, q2, q6 + +# CHECK: vcmp.s16 ge, q1, q7 @ encoding: [0x13,0xfe,0x0e,0x1f] +# CHECK-NOFP: vcmp.s16 ge, q1, q7 @ encoding: [0x13,0xfe,0x0e,0x1f] +vcmp.s16 ge, q1, q7 + +# CHECK: vcmp.s16 lt, q0, q1 @ encoding: [0x11,0xfe,0x82,0x1f] +# CHECK-NOFP: vcmp.s16 lt, q0, q1 @ encoding: [0x11,0xfe,0x82,0x1f] +vcmp.s16 lt, q0, q1 + +# CHECK: vcmp.s16 gt, q1, q7 @ encoding: [0x13,0xfe,0x0f,0x1f] +# CHECK-NOFP: vcmp.s16 gt, q1, q7 @ encoding: [0x13,0xfe,0x0f,0x1f] +vcmp.s16 gt, q1, q7 + +# CHECK: vcmp.s16 le, q2, q1 @ encoding: [0x15,0xfe,0x83,0x1f] +# CHECK-NOFP: vcmp.s16 le, q2, q1 @ encoding: [0x15,0xfe,0x83,0x1f] +vcmp.s16 le, q2, q1 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for signed integer comparison must be EQ, NE, LT, GT, LE or GE +vcmp.s16 hi, q2, q6 + +# CHECK: vcmp.u16 hi, q1, q4 @ encoding: [0x13,0xfe,0x89,0x0f] +# CHECK-NOFP: vcmp.u16 hi, q1, q4 @ encoding: [0x13,0xfe,0x89,0x0f] +vcmp.u16 hi, q1, q4 + +# CHECK: vcmp.u16 cs, q1, q4 @ encoding: [0x13,0xfe,0x09,0x0f] +# CHECK-NOFP: vcmp.u16 cs, q1, q4 @ encoding: [0x13,0xfe,0x09,0x0f] +vcmp.u16 cs, q1, q4 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for unsigned integer comparison must be EQ, NE, HS or HI +vcmp.u16 ge, q2, q6 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for unsigned integer comparison must be EQ, NE, HS or HI +vcmp.u16 ls, q2, q6 + +# CHECK: vcmp.i32 eq, q2, q7 @ encoding: [0x25,0xfe,0x0e,0x0f] +# CHECK-NOFP: vcmp.i32 eq, q2, q7 @ encoding: [0x25,0xfe,0x0e,0x0f] +vcmp.i32 eq, q2, q7 + +# CHECK: vcmp.i32 ne, q2, q4 @ encoding: [0x25,0xfe,0x88,0x0f] +# CHECK-NOFP: vcmp.i32 ne, q2, q4 @ encoding: [0x25,0xfe,0x88,0x0f] +vcmp.i32 ne, q2, q4 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for sign-independent integer comparison must be EQ or NE +vcmp.i32 lo, q2, q6 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for sign-independent integer comparison must be EQ or NE +vcmp.i32 ge, q2, q6 + +# CHECK: vcmp.s32 ge, q5, q5 @ encoding: [0x2b,0xfe,0x0a,0x1f] +# CHECK-NOFP: vcmp.s32 ge, q5, q5 @ encoding: [0x2b,0xfe,0x0a,0x1f] +vcmp.s32 ge, q5, q5 + +# CHECK: vcmp.s32 lt, q2, q2 @ encoding: [0x25,0xfe,0x84,0x1f] +# CHECK-NOFP: vcmp.s32 lt, q2, q2 @ encoding: [0x25,0xfe,0x84,0x1f] +vcmp.s32 lt, q2, q2 + +# CHECK: vcmp.s32 gt, q0, q1 @ encoding: [0x21,0xfe,0x03,0x1f] +# CHECK-NOFP: vcmp.s32 gt, q0, q1 @ encoding: [0x21,0xfe,0x03,0x1f] +vcmp.s32 gt, q0, q1 + +# CHECK: vcmp.s32 le, q5, q4 @ encoding: [0x2b,0xfe,0x89,0x1f] +# CHECK-NOFP: vcmp.s32 le, q5, q4 @ encoding: [0x2b,0xfe,0x89,0x1f] +vcmp.s32 le, q5, q4 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for signed integer comparison must be EQ, NE, LT, GT, LE or GE +vcmp.s32 ls, q2, q6 + +# CHECK: vcmp.u32 hi, q1, q4 @ encoding: [0x23,0xfe,0x89,0x0f] +# CHECK-NOFP: vcmp.u32 hi, q1, q4 @ encoding: [0x23,0xfe,0x89,0x0f] +vcmp.u32 hi, q1, q4 + +# CHECK: vcmp.u32 cs, q1, q4 @ encoding: [0x23,0xfe,0x09,0x0f] +# CHECK-NOFP: vcmp.u32 cs, q1, q4 @ encoding: [0x23,0xfe,0x09,0x0f] +vcmp.u32 cs, q1, q4 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for unsigned integer comparison must be EQ, NE, HS or HI +vcmp.u32 vs, q2, q6 + +# ERROR: [[@LINE+1]]:10: {{error|note}}: condition code for unsigned integer comparison must be EQ, NE, HS or HI +vcmp.u32 mi, q2, q6 + +# CHECK: vcmp.f16 gt, q4, zr @ encoding: [0x39,0xfe,0x6f,0x1f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 gt, q4, zr @ encoding: [0x39,0xfe,0x6f,0x1f] +vcmp.f16 gt, q4, zr + +# CHECK: vcmp.f16 eq, q4, r12 @ encoding: [0x39,0xfe,0x4c,0x0f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f16 eq, q4, r12 @ encoding: [0x39,0xfe,0x4c,0x0f] +vcmp.f16 eq, q4, r12 + +# CHECK: vcmp.f32 ne, q3, r0 @ encoding: [0x37,0xee,0xc0,0x0f] +# ERROR-NOFP: [[@LINE+2]]:1: {{error|note}}: instruction requires: mve.fp +# CHECK-NOFP-NOT: vcmp.f32 ne, q3, r0 @ encoding: [0x37,0xee,0xc0,0x0f] +vcmp.f32 ne, q3, r0 + +# CHECK: vcmp.i8 eq, q1, r0 @ encoding: [0x03,0xfe,0x40,0x0f] +# CHECK-NOFP: vcmp.i8 eq, q1, r0 @ encoding: [0x03,0xfe,0x40,0x0f] +vcmp.i8 eq, q1, r0 + +# CHECK: vcmp.s8 le, q1, r0 @ encoding: [0x03,0xfe,0xe0,0x1f] +# CHECK-NOFP: vcmp.s8 le, q1, r0 @ encoding: [0x03,0xfe,0xe0,0x1f] +vcmp.s8 le, q1, r0 + +# CHECK: vcmp.u8 cs, q1, r0 @ encoding: [0x03,0xfe,0x60,0x0f] +# CHECK-NOFP: vcmp.u8 cs, q1, r0 @ encoding: [0x03,0xfe,0x60,0x0f] +vcmp.u8 cs, q1, r0 + +# CHECK: vcmp.i16 eq, q5, r10 @ encoding: [0x1b,0xfe,0x4a,0x0f] +# CHECK-NOFP: vcmp.i16 eq, q5, r10 @ encoding: [0x1b,0xfe,0x4a,0x0f] +vcmp.i16 eq, q5, r10 + +# CHECK: vcmp.i32 eq, q1, r4 @ encoding: [0x23,0xfe,0x44,0x0f] +# CHECK-NOFP: vcmp.i32 eq, q1, r4 @ encoding: [0x23,0xfe,0x44,0x0f] +vcmp.i32 eq, q1, r4 + +vpste +vcmpt.i8 eq, q0, r0 +vcmpe.i16 ne, q0, r0 +# CHECK: vpste @ encoding: [0x71,0xfe,0x4d,0x8f] +# CHECK-NOFP: vpste @ encoding: [0x71,0xfe,0x4d,0x8f] +# CHECK: vcmpt.i8 eq, q0, r0 @ encoding: [0x01,0xfe,0x40,0x0f] +# CHECK-NOFP: vcmpt.i8 eq, q0, r0 @ encoding: [0x01,0xfe,0x40,0x0f] +# CHECK: vcmpe.i16 ne, q0, r0 @ encoding: [0x11,0xfe,0xc0,0x0f] +# CHECK-NOFP: vcmpe.i16 ne, q0, r0 @ encoding: [0x11,0xfe,0xc0,0x0f] + +# Ensure the scalar FP instructions VCMP and VCMPE are still correctly +# distinguished, in spite of VCMPE sometimes being a VPT-suffixed +# version of VCMP with identical encoding. +vcmp.f16 s0,s1 +vcmpe.f16 s0,s1 +# CHECK: vcmp.f16 s0, s1 @ encoding: [0xb4,0xee,0x60,0x09] +# CHECK: vcmpe.f16 s0, s1 @ encoding: [0xb4,0xee,0xe0,0x09] +# CHECK-NOFP-NOT: vcmp.f16 s0, s1 @ encoding: [0xb4,0xee,0x60,0x09] +# CHECK-NOFP-NOT: vcmpe.f16 s0, s1 @ encoding: [0xb4,0xee,0xe0,0x09] + +itt eq +vcmpeq.f32 s0, s1 +vcmpeeq.f32 s0, s1 +# CHECK: itt eq @ encoding: [0x04,0xbf] +# CHECK: vcmpeq.f32 s0, s1 @ encoding: [0xb4,0xee,0x60,0x0a] +# CHECK-NOFP-NOT: vcmpeq.f32 s0, s1 @ encoding: [0xb4,0xee,0x60,0x0a] +# CHECK: vcmpeeq.f32 s0, s1 @ encoding: [0xb4,0xee,0xe0,0x0a] +# CHECK-NOFP-NOT: vcmpeeq.f32 s0, s1 @ encoding: [0xb4,0xee,0xe0,0x0a] Index: llvm/trunk/test/MC/Disassembler/ARM/mve-vcmp.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/mve-vcmp.txt +++ llvm/trunk/test/MC/Disassembler/ARM/mve-vcmp.txt @@ -0,0 +1,179 @@ +# 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 + +# CHECK: vcmp.f16 eq, q0, q4 @ encoding: [0x31,0xfe,0x08,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x31,0xfe,0x08,0x0f] + +# CHECK: vcmp.f16 ne, q2, q7 @ encoding: [0x35,0xfe,0x8e,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x35,0xfe,0x8e,0x0f] + +# CHECK: vcmp.f16 ge, q0, q0 @ encoding: [0x31,0xfe,0x00,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x31,0xfe,0x00,0x1f] + +# CHECK: vcmp.f16 lt, q0, q1 @ encoding: [0x31,0xfe,0x82,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x31,0xfe,0x82,0x1f] + +# CHECK: vcmp.f16 gt, q1, q4 @ encoding: [0x33,0xfe,0x09,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x33,0xfe,0x09,0x1f] + +# CHECK: vcmp.f16 le, q2, q6 @ encoding: [0x35,0xfe,0x8d,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x35,0xfe,0x8d,0x1f] + +# CHECK: vcmp.f32 eq, q2, q5 @ encoding: [0x35,0xee,0x0a,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x35,0xee,0x0a,0x0f] + +# CHECK: vcmp.f32 ne, q3, q4 @ encoding: [0x37,0xee,0x88,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x37,0xee,0x88,0x0f] + +# CHECK: vcmp.f32 ge, q0, q7 @ encoding: [0x31,0xee,0x0e,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x31,0xee,0x0e,0x1f] + +# CHECK: vcmp.f32 lt, q5, q2 @ encoding: [0x3b,0xee,0x84,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x3b,0xee,0x84,0x1f] + +# CHECK: vcmp.f32 gt, q2, q7 @ encoding: [0x35,0xee,0x0f,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x35,0xee,0x0f,0x1f] + +# CHECK: vcmp.f32 le, q2, q4 @ encoding: [0x35,0xee,0x89,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x35,0xee,0x89,0x1f] + +# CHECK: vcmp.i8 eq, q4, q6 @ encoding: [0x09,0xfe,0x0c,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x09,0xfe,0x0c,0x0f] + +# CHECK: vcmp.i8 ne, q2, q2 @ encoding: [0x05,0xfe,0x84,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x05,0xfe,0x84,0x0f] + +# CHECK: vcmp.s8 ge, q0, q0 @ encoding: [0x01,0xfe,0x00,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x01,0xfe,0x00,0x1f] + +# CHECK: vcmp.s8 lt, q2, q7 @ encoding: [0x05,0xfe,0x8e,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x05,0xfe,0x8e,0x1f] + +# CHECK: vcmp.s8 gt, q4, q3 @ encoding: [0x09,0xfe,0x07,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x09,0xfe,0x07,0x1f] + +# CHECK: vcmp.s8 le, q7, q3 @ encoding: [0x0f,0xfe,0x87,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x0f,0xfe,0x87,0x1f] + +# CHECK: vcmp.u8 hi, q1, q4 @ encoding: [0x03,0xfe,0x89,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x03,0xfe,0x89,0x0f] + +# CHECK: vcmp.u8 cs, q1, q4 @ encoding: [0x03,0xfe,0x09,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x03,0xfe,0x09,0x0f] + +# CHECK: vcmp.i16 eq, q4, q7 @ encoding: [0x19,0xfe,0x0e,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x19,0xfe,0x0e,0x0f] + +# CHECK: vcmp.i16 ne, q2, q1 @ encoding: [0x15,0xfe,0x82,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x15,0xfe,0x82,0x0f] + +# CHECK: vcmp.s16 ge, q1, q7 @ encoding: [0x13,0xfe,0x0e,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x13,0xfe,0x0e,0x1f] + +# CHECK: vcmp.s16 lt, q0, q1 @ encoding: [0x11,0xfe,0x82,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x11,0xfe,0x82,0x1f] + +# CHECK: vcmp.s16 gt, q1, q7 @ encoding: [0x13,0xfe,0x0f,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x13,0xfe,0x0f,0x1f] + +# CHECK: vcmp.s16 le, q2, q1 @ encoding: [0x15,0xfe,0x83,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x15,0xfe,0x83,0x1f] + +# CHECK: vcmp.u16 hi, q1, q4 @ encoding: [0x13,0xfe,0x89,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x13,0xfe,0x89,0x0f] + +# CHECK: vcmp.u16 cs, q1, q4 @ encoding: [0x13,0xfe,0x09,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x13,0xfe,0x09,0x0f] + +# CHECK: vcmp.i32 eq, q2, q7 @ encoding: [0x25,0xfe,0x0e,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x25,0xfe,0x0e,0x0f] + +# CHECK: vcmp.i32 ne, q2, q4 @ encoding: [0x25,0xfe,0x88,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x25,0xfe,0x88,0x0f] + +# CHECK: vcmp.s32 ge, q5, q5 @ encoding: [0x2b,0xfe,0x0a,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x2b,0xfe,0x0a,0x1f] + +# CHECK: vcmp.s32 lt, q2, q2 @ encoding: [0x25,0xfe,0x84,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x25,0xfe,0x84,0x1f] + +# CHECK: vcmp.s32 gt, q0, q1 @ encoding: [0x21,0xfe,0x03,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x21,0xfe,0x03,0x1f] + +# CHECK: vcmp.s32 le, q5, q4 @ encoding: [0x2b,0xfe,0x89,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x2b,0xfe,0x89,0x1f] + +# CHECK: vcmp.u32 hi, q1, q4 @ encoding: [0x23,0xfe,0x89,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x23,0xfe,0x89,0x0f] + +# CHECK: vcmp.u32 cs, q1, q4 @ encoding: [0x23,0xfe,0x09,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x23,0xfe,0x09,0x0f] + +# CHECK: vcmp.f16 gt, q4, zr @ encoding: [0x39,0xfe,0x6f,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x39,0xfe,0x6f,0x1f] + +# CHECK: vcmp.f16 eq, q4, r12 @ encoding: [0x39,0xfe,0x4c,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x39,0xfe,0x4c,0x0f] + +# CHECK: vcmp.f32 ne, q3, r0 @ encoding: [0x37,0xee,0xc0,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x37,0xee,0xc0,0x0f] + +# CHECK: vcmp.i8 eq, q1, r0 @ encoding: [0x03,0xfe,0x40,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x03,0xfe,0x40,0x0f] + +# CHECK: vcmp.s8 le, q1, r0 @ encoding: [0x03,0xfe,0xe0,0x1f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x03,0xfe,0xe0,0x1f] + +# CHECK: vcmp.u8 cs, q1, r0 @ encoding: [0x03,0xfe,0x60,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x03,0xfe,0x60,0x0f] + +# CHECK: vcmp.i16 eq, q5, r10 @ encoding: [0x1b,0xfe,0x4a,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x1b,0xfe,0x4a,0x0f] + +# CHECK: vcmp.i32 eq, q1, r4 @ encoding: [0x23,0xfe,0x44,0x0f] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x23,0xfe,0x44,0x0f]