[llvm] r333263 - [AArch64][SVE] Asm: Support for DUP (immediate) instructions.

Sander de Smalen via llvm-commits llvm-commits at lists.llvm.org
Fri May 25 02:47:52 PDT 2018


Author: s.desmalen
Date: Fri May 25 02:47:52 2018
New Revision: 333263

URL: http://llvm.org/viewvc/llvm-project?rev=333263&view=rev
Log:
[AArch64][SVE] Asm: Support for DUP (immediate) instructions.

Unpredicated copy of optionally-shifted immediate to SVE vector,
along with MOV-aliases.

This patch contains parsing and printing support for
cpy_imm8_opt_lsl_(i8|i16|i32|i64). This operand allows a signed value in
the range -128 to +127. For element widths of 16 bits or higher it may
also be a signed multiple of 256 in the range -32768 to +32512.
For element-width of 8 bits a range of -128 to 255 is accepted, since a copy
of a byte can be considered either signed/unsigned.

Note: This patch renames tryParseAddSubImm() -> tryParseImmWithOptionalShift()
and moves the behaviour of trying to shift a plain immediate by an allowed
shift-value to its addImmWithOptionalShiftOperands() method, so that the
parsing itself is generic and allows immediates from multiple shifted operands.
This is done because an immediate can be divisible by both shifted operands.

Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D47309


Modified:
    llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td
    llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
    llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
    llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
    llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
    llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
    llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td
    llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s
    llvm/trunk/test/MC/AArch64/SVE/dup.s
    llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s
    llvm/trunk/test/MC/AArch64/SVE/mov.s

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td Fri May 25 02:47:52 2018
@@ -805,11 +805,13 @@ def move_vec_shift : Operand<i32> {
 let DiagnosticType = "AddSubSecondSource" in {
   def AddSubImmOperand : AsmOperandClass {
     let Name = "AddSubImm";
-    let ParserMethod = "tryParseAddSubImm";
+    let ParserMethod = "tryParseImmWithOptionalShift";
+    let RenderMethod = "addImmWithOptionalShiftOperands<12>";
   }
   def AddSubImmNegOperand : AsmOperandClass {
     let Name = "AddSubImmNeg";
-    let ParserMethod = "tryParseAddSubImm";
+    let ParserMethod = "tryParseImmWithOptionalShift";
+    let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
   }
 }
 // An ADD/SUB immediate shifter operand:

Modified: llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td Fri May 25 02:47:52 2018
@@ -20,6 +20,9 @@ let Predicates = [HasSVE] in {
   defm ADD_ZPmZ  : sve_int_bin_pred_arit_0<0b000, "add">;
   defm SUB_ZPmZ  : sve_int_bin_pred_arit_0<0b001, "sub">;
 
+  // Splat immediate (unpredicated)
+  defm DUP_ZI   : sve_int_dup_imm<"dup">;
+
   // continuous load with reg+immediate
   defm LD1B_IMM    : sve_mem_cld_si<0b0000, "ld1b",  Z_b, ZPR8>;
   defm LD1B_H_IMM  : sve_mem_cld_si<0b0001, "ld1b",  Z_h, ZPR16>;

Modified: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp Fri May 25 02:47:52 2018
@@ -133,7 +133,7 @@ private:
   OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
   OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
   OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
-  OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands);
+  OperandMatchResultTy tryParseImmWithOptionalShift(OperandVector &Operands);
   OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
   bool tryParseNeonVectorRegister(OperandVector &Operands);
   OperandMatchResultTy tryParseVectorIndex(OperandVector &Operands);
@@ -636,6 +636,27 @@ public:
 
   bool isShiftedImm() const { return Kind == k_ShiftedImm; }
 
+  /// Returns the immediate value as a pair of (imm, shift) if the immediate is
+  /// a shifted immediate by value 'Shift' or '0', or if it is an unshifted
+  /// immediate that can be shifted by 'Shift'.
+  template <unsigned Width>
+  Optional<std::pair<int64_t, unsigned> > getShiftedVal() const {
+    if (isShiftedImm() && Width == getShiftedImmShift())
+      if (auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
+        return std::make_pair(CE->getValue(), Width);
+
+    if (isImm())
+      if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
+        int64_t Val = CE->getValue();
+        if ((Val != 0) && ((Val >> Width) << Width) == Val)
+          return std::make_pair(Val >> Width, Width);
+        else
+          return std::make_pair(Val, 0u);
+      }
+
+    return {};
+  }
+
   bool isAddSubImm() const {
     if (!isShiftedImm() && !isImm())
       return false;
@@ -673,8 +694,8 @@ public:
     }
 
     // If it's a constant, it should be a real immediate in range:
-    if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
-      return CE->getValue() >= 0 && CE->getValue() <= 0xfff;
+    if (auto ShiftedVal = getShiftedVal<12>())
+      return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
 
     // If it's an expression, we hope for the best and let the fixup/relocation
     // code deal with it.
@@ -701,6 +722,26 @@ public:
     return CE != nullptr && CE->getValue() < 0 && -CE->getValue() <= 0xfff;
   }
 
+  // Signed value in the range -128 to +127. For element widths of
+  // 16 bits or higher it may also be a signed multiple of 256 in the
+  // range -32768 to +32512.
+  // For element-width of 8 bits a range of -128 to 255 is accepted,
+  // since a copy of a byte can be either signed/unsigned.
+  template <typename T>
+  DiagnosticPredicate isSVECpyImm() const {
+    if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
+      return DiagnosticPredicateTy::NoMatch;
+
+    bool IsByte =
+        std::is_same<int8_t, typename std::make_signed<T>::type>::value;
+    if (auto ShiftedImm = getShiftedVal<8>())
+      if (!(IsByte && ShiftedImm->second) &&
+          AArch64_AM::isSVECpyImm<T>(ShiftedImm->first << ShiftedImm->second))
+        return DiagnosticPredicateTy::Match;
+
+    return DiagnosticPredicateTy::NearMatch;
+  }
+
   bool isCondCode() const { return Kind == k_CondCode; }
 
   bool isSIMDImmType10() const {
@@ -1284,9 +1325,13 @@ public:
     addExpr(Inst, getImm());
   }
 
-  void addAddSubImmOperands(MCInst &Inst, unsigned N) const {
+  template <int Shift>
+  void addImmWithOptionalShiftOperands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && "Invalid number of operands!");
-    if (isShiftedImm()) {
+    if (auto ShiftedVal = getShiftedVal<Shift>()) {
+      Inst.addOperand(MCOperand::createImm(ShiftedVal->first));
+      Inst.addOperand(MCOperand::createImm(ShiftedVal->second));
+    } else if (isShiftedImm()) {
       addExpr(Inst, getShiftedImmVal());
       Inst.addOperand(MCOperand::createImm(getShiftedImmShift()));
     } else {
@@ -1295,16 +1340,14 @@ public:
     }
   }
 
-  void addAddSubImmNegOperands(MCInst &Inst, unsigned N) const {
+  template <int Shift>
+  void addImmNegWithOptionalShiftOperands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && "Invalid number of operands!");
-
-    const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm();
-    const MCConstantExpr *CE = cast<MCConstantExpr>(MCE);
-    int64_t Val = -CE->getValue();
-    unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0;
-
-    Inst.addOperand(MCOperand::createImm(Val));
-    Inst.addOperand(MCOperand::createImm(ShiftAmt));
+    if (auto ShiftedVal = getShiftedVal<Shift>()) {
+      Inst.addOperand(MCOperand::createImm(-ShiftedVal->first));
+      Inst.addOperand(MCOperand::createImm(ShiftedVal->second));
+    } else
+      llvm_unreachable("Not a shifted negative immediate");
   }
 
   void addCondCodeOperands(MCInst &Inst, unsigned N) const {
@@ -2269,9 +2312,10 @@ AArch64AsmParser::tryParseFPImm(OperandV
   return MatchOperand_ParseFail;
 }
 
-/// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand
+/// tryParseImmWithOptionalShift - Parse immediate operand, optionally with
+/// a shift suffix, for example '#1, lsl #12'.
 OperandMatchResultTy
-AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
+AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) {
   MCAsmParser &Parser = getParser();
   SMLoc S = getLoc();
 
@@ -2285,18 +2329,9 @@ AArch64AsmParser::tryParseAddSubImm(Oper
   if (parseSymbolicImmVal(Imm))
     return MatchOperand_ParseFail;
   else if (Parser.getTok().isNot(AsmToken::Comma)) {
-    uint64_t ShiftAmount = 0;
-    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm);
-    if (MCE) {
-      int64_t Val = MCE->getValue();
-      if (Val > 0xfff && (Val & 0xfff) == 0) {
-        Imm = MCConstantExpr::create(Val >> 12, getContext());
-        ShiftAmount = 12;
-      }
-    }
     SMLoc E = Parser.getTok().getLoc();
-    Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
-                                                        getContext()));
+    Operands.push_back(
+        AArch64Operand::CreateImm(Imm, S, E, getContext()));
     return MatchOperand_Success;
   }
 
@@ -2328,6 +2363,13 @@ AArch64AsmParser::tryParseAddSubImm(Oper
   }
   Parser.Lex(); // Eat the number
 
+  // Just in case the optional lsl #0 is used for immediates other than zero.
+  if (ShiftAmount == 0 && Imm != 0) {
+    SMLoc E = Parser.getTok().getLoc();
+    Operands.push_back(AArch64Operand::CreateImm(Imm, S, E, getContext()));
+    return MatchOperand_Success;
+  }
+
   SMLoc E = Parser.getTok().getLoc();
   Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
                                                       S, E, getContext()));
@@ -3765,6 +3807,14 @@ bool AArch64AsmParser::showMatchError(SM
     return Error(Loc, "immediate must be an integer in range [1, 32].");
   case Match_InvalidImm1_64:
     return Error(Loc, "immediate must be an integer in range [1, 64].");
+  case Match_InvalidSVECpyImm8:
+    return Error(Loc, "immediate must be an integer in range [-128, 255]"
+                      " with a shift amount of 0");
+  case Match_InvalidSVECpyImm16:
+  case Match_InvalidSVECpyImm32:
+  case Match_InvalidSVECpyImm64:
+    return Error(Loc, "immediate must be an integer in range [-128, 127] or a "
+                      "multiple of 256 in range [-32768, 32512]");
   case Match_InvalidIndex1:
     return Error(Loc, "expected lane specifier '[1]'");
   case Match_InvalidIndexB:
@@ -4293,6 +4343,10 @@ bool AArch64AsmParser::MatchAndEmitInstr
   case Match_InvalidImm1_16:
   case Match_InvalidImm1_32:
   case Match_InvalidImm1_64:
+  case Match_InvalidSVECpyImm8:
+  case Match_InvalidSVECpyImm16:
+  case Match_InvalidSVECpyImm32:
+  case Match_InvalidSVECpyImm64:
   case Match_InvalidIndex1:
   case Match_InvalidIndexB:
   case Match_InvalidIndexH:

Modified: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp Fri May 25 02:47:52 2018
@@ -207,6 +207,9 @@ static DecodeStatus DecodeSVELogicalImmI
 template<int Bits>
 static DecodeStatus DecodeSImm(llvm::MCInst &Inst, uint64_t Imm,
                                uint64_t Address, const void *Decoder);
+template <int ElementWidth>
+static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm,
+                                     uint64_t Addr, const void *Decoder);
 
 static bool Check(DecodeStatus &Out, DecodeStatus In) {
   switch (In) {
@@ -1775,3 +1778,15 @@ static DecodeStatus DecodeSImm(llvm::MCI
   return Success;
 }
 
+// Decode 8-bit signed/unsigned immediate for a given element width.
+template <int ElementWidth>
+static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm,
+                                      uint64_t Addr, const void *Decoder) {
+  unsigned Val = (uint8_t)Imm;
+  unsigned Shift = (Imm & 0x100) ? 8 : 0;
+  if (ElementWidth == 8 && Shift)
+    return Fail;
+  Inst.addOperand(MCOperand::createImm(Val));
+  Inst.addOperand(MCOperand::createImm(Shift));
+  return Success;
+}

Modified: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp Fri May 25 02:47:52 2018
@@ -1437,3 +1437,46 @@ void AArch64InstPrinter::printSVERegOp(c
   if (suffix != 0)
     O << '.' << suffix;
 }
+
+template <typename T>
+void AArch64InstPrinter::printImmSVE(T Value, raw_ostream &O) {
+  typename std::make_unsigned<T>::type HexValue = Value;
+
+  if (getPrintImmHex())
+    O << '#' << formatHex((uint64_t)HexValue);
+  else
+    O << '#' << formatDec(Value);
+
+  if (CommentStream) {
+    // Do the opposite to that used for instruction operands.
+    if (getPrintImmHex())
+      *CommentStream << '=' << formatDec(HexValue) << '\n';
+    else
+      *CommentStream << '=' << formatHex((uint64_t)Value) << '\n';
+  }
+}
+
+template <typename T>
+void AArch64InstPrinter::printImm8OptLsl(const MCInst *MI, unsigned OpNum,
+                                         const MCSubtargetInfo &STI,
+                                         raw_ostream &O) {
+  unsigned UnscaledVal = MI->getOperand(OpNum).getImm();
+  unsigned Shift = MI->getOperand(OpNum + 1).getImm();
+  assert(AArch64_AM::getShiftType(Shift) == AArch64_AM::LSL &&
+         "Unexepected shift type!");
+
+  // #0 lsl #8 is never pretty printed
+  if ((UnscaledVal == 0) && (AArch64_AM::getShiftValue(Shift) != 0)) {
+    O << '#' << formatImm(UnscaledVal);
+    printShifter(MI, OpNum + 1, STI, O);
+    return;
+  }
+
+  T Val;
+  if (std::is_signed<T>())
+    Val = (int8_t)UnscaledVal * (1 << AArch64_AM::getShiftValue(Shift));
+  else
+    Val = (uint8_t)UnscaledVal * (1 << AArch64_AM::getShiftValue(Shift));
+
+  printImmSVE(Val, O);
+}

Modified: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h (original)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h Fri May 25 02:47:52 2018
@@ -57,6 +57,7 @@ protected:
                 raw_ostream &O);
   void printImmHex(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                    raw_ostream &O);
+  template <typename T> void printImmSVE(T Value, raw_ostream &O);
   void printPostIncOperand(const MCInst *MI, unsigned OpNo, unsigned Imm,
                            raw_ostream &O);
   template <int Amount>
@@ -168,6 +169,9 @@ protected:
   void printGPRSeqPairsClassOperand(const MCInst *MI, unsigned OpNum,
                                     const MCSubtargetInfo &STI,
                                     raw_ostream &O);
+  template <typename T>
+  void printImm8OptLsl(const MCInst *MI, unsigned OpNum,
+                       const MCSubtargetInfo &STI, raw_ostream &O);
   void printSVEPattern(const MCInst *MI, unsigned OpNum,
                        const MCSubtargetInfo &STI, raw_ostream &O);
   template <char = 0>

Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h Fri May 25 02:47:52 2018
@@ -765,6 +765,17 @@ static inline bool isSVEMaskOfIdenticalE
   return all_of(Vec.Parts, [Vec](T Elem) { return Elem == Vec.Parts[0]; });
 }
 
+/// Returns true if Imm is valid for CPY/DUP.
+template <typename T>
+static inline bool isSVECpyImm(int64_t Imm) {
+  if (std::is_same<int8_t, typename std::make_signed<T>::type>::value)
+    return uint8_t(Imm) == Imm || int8_t(Imm) == Imm;
+  else
+    return int8_t(Imm) == Imm || int16_t(Imm & ~0xff) == Imm;
+
+  llvm_unreachable("Unsupported element width");
+}
+
 inline static bool isAnyMOVZMovAlias(uint64_t Value, int RegWidth) {
   for (int Shift = 0; Shift <= RegWidth - 16; Shift += 16)
     if ((Value & ~(0xffffULL << Shift)) == 0)

Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp Fri May 25 02:47:52 2018
@@ -163,6 +163,10 @@ public:
                                 SmallVectorImpl<MCFixup> &Fixups,
                                 const MCSubtargetInfo &STI) const;
 
+  uint32_t getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
+                         SmallVectorImpl<MCFixup> &Fixups,
+                         const MCSubtargetInfo &STI) const;
+
   unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
                    const MCSubtargetInfo &STI) const;
 
@@ -509,6 +513,24 @@ AArch64MCCodeEmitter::getVecShiftL8OpVal
   return MO.getImm() - 8;
 }
 
+uint32_t
+AArch64MCCodeEmitter::getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
+                                    SmallVectorImpl<MCFixup> &Fixups,
+                                    const MCSubtargetInfo &STI) const {
+  // Test shift
+  auto ShiftOpnd = MI.getOperand(OpIdx + 1).getImm();
+  assert(AArch64_AM::getShiftType(ShiftOpnd) == AArch64_AM::LSL &&
+         "Unexpected shift type for imm8_opt_lsl immediate.");
+
+  unsigned ShiftVal = AArch64_AM::getShiftValue(ShiftOpnd);
+  assert((ShiftVal == 0 || ShiftVal == 8) &&
+         "Unexpected shift value for imm8_opt_lsl immediate.");
+
+  // Test immediate
+  auto Immediate = MI.getOperand(OpIdx).getImm();
+  return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
+}
+
 /// getMoveVecShifterOpValue - Return the encoded value for the vector move
 /// shifter (MSL).
 uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(

Modified: llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td (original)
+++ llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td Fri May 25 02:47:52 2018
@@ -84,7 +84,6 @@ def sve_logical_imm32 : Operand<i64> {
   }];
 }
 
-//===----------------------------------------------------------------------===//
 class SVELogicalImmNotOperand<int Width> : AsmOperandClass {
   let Name = "SVELogicalImm" # Width # "Not";
   let DiagnosticType = "LogicalSecondSource";
@@ -104,6 +103,43 @@ def sve_logical_imm32_not : Operand<i64>
   let ParserMatchClass = SVELogicalImmNotOperand<32>;
 }
 
+class SVEShiftedImmOperand<int ElementWidth, string Infix, string Predicate>
+    : AsmOperandClass {
+  let Name = "SVE" # Infix # "Imm" # ElementWidth;
+  let DiagnosticType = "Invalid" # Name;
+  let RenderMethod = "addImmWithOptionalShiftOperands<8>";
+  let ParserMethod = "tryParseImmWithOptionalShift";
+  let PredicateMethod = Predicate;
+}
+
+def SVECpyImmOperand8  : SVEShiftedImmOperand<8,  "Cpy", "isSVECpyImm<int8_t>">;
+def SVECpyImmOperand16 : SVEShiftedImmOperand<16, "Cpy", "isSVECpyImm<int16_t>">;
+def SVECpyImmOperand32 : SVEShiftedImmOperand<32, "Cpy", "isSVECpyImm<int32_t>">;
+def SVECpyImmOperand64 : SVEShiftedImmOperand<64, "Cpy", "isSVECpyImm<int64_t>">;
+
+class imm8_opt_lsl<int ElementWidth, string printType,
+                   AsmOperandClass OpndClass, code Predicate>
+    : Operand<i32>, ImmLeaf<i32, Predicate> {
+  let EncoderMethod = "getImm8OptLsl";
+  let DecoderMethod = "DecodeImm8OptLsl<" # ElementWidth # ">";
+  let PrintMethod = "printImm8OptLsl<" # printType # ">";
+  let ParserMatchClass = OpndClass;
+  let MIOperandInfo = (ops i32imm, i32imm);
+}
+
+def cpy_imm8_opt_lsl_i8  : imm8_opt_lsl<8,  "int8_t",  SVECpyImmOperand8,  [{
+  return AArch64_AM::isSVECpyImm<int8_t>(Imm);
+}]>;
+def cpy_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "int16_t", SVECpyImmOperand16, [{
+  return AArch64_AM::isSVECpyImm<int16_t>(Imm);
+}]>;
+def cpy_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "int32_t", SVECpyImmOperand32, [{
+  return AArch64_AM::isSVECpyImm<int32_t>(Imm);
+}]>;
+def cpy_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "int64_t", SVECpyImmOperand64, [{
+  return AArch64_AM::isSVECpyImm<int64_t>(Imm);
+}]>;
+
 //===----------------------------------------------------------------------===//
 // SVE PTrue - These are used extensively throughout the pattern matching so
 //             it's important we define them first.
@@ -352,6 +388,42 @@ multiclass sve_int_bin_pred_arit_0<bits<
   def _D : sve_int_bin_pred_arit_log<0b11, 0b00, opc, asm, ZPR64>;
 }
 
+//===----------------------------------------------------------------------===//
+// SVE Integer Wide Immediate - Unpredicated Group
+//===----------------------------------------------------------------------===//
+class sve_int_dup_imm<bits<2> sz8_64, string asm,
+                      ZPRRegOp zprty, Operand immtype>
+: I<(outs zprty:$Zd), (ins immtype:$imm),
+  asm, "\t$Zd, $imm",
+  "",
+  []>, Sched<[]> {
+  bits<5> Zd;
+  bits<9> imm;
+  let Inst{31-24} = 0b00100101;
+  let Inst{23-22} = sz8_64;
+  let Inst{21-14} = 0b11100011;
+  let Inst{13}    = imm{8};   // sh
+  let Inst{12-5}  = imm{7-0}; // imm8
+  let Inst{4-0}   = Zd;
+
+  let isReMaterializable = 1;
+}
+
+multiclass sve_int_dup_imm<string asm> {
+  def _B : sve_int_dup_imm<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8>;
+  def _H : sve_int_dup_imm<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16>;
+  def _S : sve_int_dup_imm<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32>;
+  def _D : sve_int_dup_imm<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64>;
+
+  def : InstAlias<"mov $Zd, $imm",
+                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, cpy_imm8_opt_lsl_i8:$imm), 1>;
+  def : InstAlias<"mov $Zd, $imm",
+                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, cpy_imm8_opt_lsl_i16:$imm), 1>;
+  def : InstAlias<"mov $Zd, $imm",
+                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
+  def : InstAlias<"mov $Zd, $imm",
+                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;
+}
 
 //===----------------------------------------------------------------------===//
 //SVE Index Generation Group

Modified: llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s (original)
+++ llvm/trunk/test/MC/AArch64/SVE/dup-diagnostics.s Fri May 25 02:47:52 2018
@@ -17,3 +17,122 @@ dup z0.d, xzr
 // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
 // CHECK-NEXT: dup z0.d, xzr
 // CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+
+// --------------------------------------------------------------------------//
+// Invalid immediates
+
+dup z0.b, #0, lsl #8      // #0, lsl #8 is not valid for .b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: dup z0.b, #0, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.b, #-129
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: dup z0.b, #-129
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.b, #-1, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: dup z0.b, #-1, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.b, #256
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: dup z0.b, #256
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.b, #1, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: dup z0.b, #1, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.h, #-33024
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.h, #-33024
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.h, #-32769
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.h, #-32769
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.h, #-129, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.h, #-129, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.h, #32513
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.h, #32513
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.h, #32768
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.h, #32768
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.h, #128, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.h, #128, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.s, #-33024
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.s, #-33024
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.s, #-32769
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.s, #-32769
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.s, #-129, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.s, #-129, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.s, #32513
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.s, #32513
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.s, #32768
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.s, #32768
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.s, #128, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.s, #128, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.d, #-33024
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.d, #-33024
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.d, #-32769
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.d, #-32769
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.d, #-129, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.d, #-129, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.d, #32513
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.d, #32513
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.d, #32768
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.d, #32768
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup z0.d, #128, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: dup z0.d, #128, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

Modified: llvm/trunk/test/MC/AArch64/SVE/dup.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/SVE/dup.s?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/SVE/dup.s (original)
+++ llvm/trunk/test/MC/AArch64/SVE/dup.s Fri May 25 02:47:52 2018
@@ -54,3 +54,129 @@ dup     z31.b, wsp
 // CHECK-ENCODING: [0xff,0x3b,0x20,0x05]
 // CHECK-ERROR: instruction requires: sve
 // CHECK-UNKNOWN: ff 3b 20 05 <unknown>
+
+dup     z5.b, #-128
+// CHECK-INST: mov     z5.b, #-128
+// CHECK-ENCODING: [0x05,0xd0,0x38,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 05 d0 38 25 <unknown>
+
+dup     z5.b, #127
+// CHECK-INST: mov     z5.b, #127
+// CHECK-ENCODING: [0xe5,0xcf,0x38,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e5 cf 38 25 <unknown>
+
+dup     z5.b, #255
+// CHECK-INST: mov     z5.b, #-1
+// CHECK-ENCODING: [0xe5,0xdf,0x38,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e5 df 38 25 <unknown>
+
+dup     z21.h, #-128
+// CHECK-INST: mov     z21.h, #-128
+// CHECK-ENCODING: [0x15,0xd0,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 d0 78 25 <unknown>
+
+dup     z21.h, #-128, lsl #8
+// CHECK-INST: mov     z21.h, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 78 25 <unknown>
+
+dup     z21.h, #-32768
+// CHECK-INST: mov     z21.h, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 78 25 <unknown>
+
+dup     z21.h, #127
+// CHECK-INST: mov     z21.h, #127
+// CHECK-ENCODING: [0xf5,0xcf,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 cf 78 25 <unknown>
+
+dup     z21.h, #127, lsl #8
+// CHECK-INST: mov     z21.h, #32512
+// CHECK-ENCODING: [0xf5,0xef,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef 78 25 <unknown>
+
+dup     z21.h, #32512
+// CHECK-INST: mov     z21.h, #32512
+// CHECK-ENCODING: [0xf5,0xef,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef 78 25 <unknown>
+
+dup     z21.s, #-128
+// CHECK-INST: mov     z21.s, #-128
+// CHECK-ENCODING: [0x15,0xd0,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 d0 b8 25 <unknown>
+
+dup     z21.s, #-128, lsl #8
+// CHECK-INST: mov     z21.s, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 b8 25 <unknown>
+
+dup     z21.s, #-32768
+// CHECK-INST: mov     z21.s, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 b8 25 <unknown>
+
+dup     z21.s, #127
+// CHECK-INST: mov     z21.s, #127
+// CHECK-ENCODING: [0xf5,0xcf,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 cf b8 25 <unknown>
+
+dup     z21.s, #127, lsl #8
+// CHECK-INST: mov     z21.s, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef b8 25 <unknown>
+
+dup     z21.s, #32512
+// CHECK-INST: mov     z21.s, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef b8 25 <unknown>
+
+dup     z21.d, #-128
+// CHECK-INST: mov     z21.d, #-128
+// CHECK-ENCODING: [0x15,0xd0,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 d0 f8 25 <unknown>
+
+dup     z21.d, #-128, lsl #8
+// CHECK-INST: mov     z21.d, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 f8 25 <unknown>
+
+dup     z21.d, #-32768
+// CHECK-INST: mov     z21.d, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 f8 25 <unknown>
+
+dup     z21.d, #127
+// CHECK-INST: mov     z21.d, #127
+// CHECK-ENCODING: [0xf5,0xcf,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 cf f8 25 <unknown>
+
+dup     z21.d, #127, lsl #8
+// CHECK-INST: mov     z21.d, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef f8 25 <unknown>
+
+dup     z21.d, #32512
+// CHECK-INST: mov     z21.d, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef f8 25 <unknown>

Modified: llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s (original)
+++ llvm/trunk/test/MC/AArch64/SVE/mov-diagnostics.s Fri May 25 02:47:52 2018
@@ -17,3 +17,122 @@ mov z0.d, xzr
 // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
 // CHECK-NEXT: mov z0.d, xzr
 // CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+
+// --------------------------------------------------------------------------//
+// Invalid immediates
+
+mov z0.b, #0, lsl #8      // #0, lsl #8 is not valid for .b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: mov z0.b, #0, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.b, #-129
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: mov z0.b, #-129
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.b, #-1, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: mov z0.b, #-1, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.b, #256
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: mov z0.b, #256
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.b, #1, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255]
+// CHECK-NEXT: mov z0.b, #1, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.h, #-33024
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.h, #-33024
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.h, #-32769
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.h, #-32769
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.h, #-129, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.h, #-129, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.h, #32513
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.h, #32513
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.h, #32768
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.h, #32768
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.h, #128, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.h, #128, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.s, #-33024
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.s, #-33024
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.s, #-32769
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.s, #-32769
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.s, #-129, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.s, #-129, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.s, #32513
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.s, #32513
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.s, #32768
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.s, #32768
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.s, #128, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.s, #128, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.d, #-33024
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.d, #-33024
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.d, #-32769
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.d, #-32769
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.d, #-129, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.d, #-129, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.d, #32513
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.d, #32513
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.d, #32768
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.d, #32768
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+mov z0.d, #128, lsl #8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 32512]
+// CHECK-NEXT: mov z0.d, #128, lsl #8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

Modified: llvm/trunk/test/MC/AArch64/SVE/mov.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/SVE/mov.s?rev=333263&r1=333262&r2=333263&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/SVE/mov.s (original)
+++ llvm/trunk/test/MC/AArch64/SVE/mov.s Fri May 25 02:47:52 2018
@@ -54,3 +54,129 @@ mov     z31.b, wsp
 // CHECK-ENCODING: [0xff,0x3b,0x20,0x05]
 // CHECK-ERROR: instruction requires: sve
 // CHECK-UNKNOWN: ff 3b 20 05 <unknown>
+
+mov     z5.b, #-128
+// CHECK-INST: mov     z5.b, #-128
+// CHECK-ENCODING: [0x05,0xd0,0x38,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 05 d0 38 25 <unknown>
+
+mov     z5.b, #127
+// CHECK-INST: mov     z5.b, #127
+// CHECK-ENCODING: [0xe5,0xcf,0x38,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e5 cf 38 25 <unknown>
+
+mov     z5.b, #255
+// CHECK-INST: mov     z5.b, #-1
+// CHECK-ENCODING: [0xe5,0xdf,0x38,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e5 df 38 25 <unknown>
+
+mov     z21.h, #-128
+// CHECK-INST: mov     z21.h, #-128
+// CHECK-ENCODING: [0x15,0xd0,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 d0 78 25 <unknown>
+
+mov     z21.h, #-128, lsl #8
+// CHECK-INST: mov     z21.h, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 78 25 <unknown>
+
+mov     z21.h, #-32768
+// CHECK-INST: mov     z21.h, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 78 25 <unknown>
+
+mov     z21.h, #127
+// CHECK-INST: mov     z21.h, #127
+// CHECK-ENCODING: [0xf5,0xcf,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 cf 78 25 <unknown>
+
+mov     z21.h, #127, lsl #8
+// CHECK-INST: mov     z21.h, #32512
+// CHECK-ENCODING: [0xf5,0xef,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef 78 25 <unknown>
+
+mov     z21.h, #32512
+// CHECK-INST: mov     z21.h, #32512
+// CHECK-ENCODING: [0xf5,0xef,0x78,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef 78 25 <unknown>
+
+mov     z21.s, #-128
+// CHECK-INST: mov     z21.s, #-128
+// CHECK-ENCODING: [0x15,0xd0,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 d0 b8 25 <unknown>
+
+mov     z21.s, #-128, lsl #8
+// CHECK-INST: mov     z21.s, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 b8 25 <unknown>
+
+mov     z21.s, #-32768
+// CHECK-INST: mov     z21.s, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 b8 25 <unknown>
+
+mov     z21.s, #127
+// CHECK-INST: mov     z21.s, #127
+// CHECK-ENCODING: [0xf5,0xcf,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 cf b8 25 <unknown>
+
+mov     z21.s, #127, lsl #8
+// CHECK-INST: mov     z21.s, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef b8 25 <unknown>
+
+mov     z21.s, #32512
+// CHECK-INST: mov     z21.s, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xb8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef b8 25 <unknown>
+
+mov     z21.d, #-128
+// CHECK-INST: mov     z21.d, #-128
+// CHECK-ENCODING: [0x15,0xd0,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 d0 f8 25 <unknown>
+
+mov     z21.d, #-128, lsl #8
+// CHECK-INST: mov     z21.d, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 f8 25 <unknown>
+
+mov     z21.d, #-32768
+// CHECK-INST: mov     z21.d, #-32768
+// CHECK-ENCODING: [0x15,0xf0,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 15 f0 f8 25 <unknown>
+
+mov     z21.d, #127
+// CHECK-INST: mov     z21.d, #127
+// CHECK-ENCODING: [0xf5,0xcf,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 cf f8 25 <unknown>
+
+mov     z21.d, #127, lsl #8
+// CHECK-INST: mov     z21.d, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef f8 25 <unknown>
+
+mov     z21.d, #32512
+// CHECK-INST: mov     z21.d, #32512
+// CHECK-ENCODING: [0xf5,0xef,0xf8,0x25]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: f5 ef f8 25 <unknown>




More information about the llvm-commits mailing list