diff options
author | Sander de Smalen <sander.desmalen@arm.com> | 2018-06-01 07:25:46 +0000 |
---|---|---|
committer | Sander de Smalen <sander.desmalen@arm.com> | 2018-06-01 07:25:46 +0000 |
commit | 1aba34939979cea974efc019ed7208aed76fda2f (patch) | |
tree | 1ac6e7053ba4b125f6efafc741f11637a31b641b | |
parent | 0176ae243c350ec8dbef7ad7e62747ee9492ee04 (diff) |
[AArch64][SVE] Asm: Support for DUPM (masked immediate) instruction.
Unpredicated copy of repeating immediate pattern to SVE vector, along
with MOV-aliases.
Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar
Reviewed By: SjoerdMeijer
Differential Revision: https://reviews.llvm.org/D47328
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333731 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/AArch64/AArch64SVEInstrInfo.td | 1 | ||||
-rw-r--r-- | lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 6 | ||||
-rw-r--r-- | lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp | 3 | ||||
-rw-r--r-- | lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp | 19 | ||||
-rw-r--r-- | lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h | 3 | ||||
-rw-r--r-- | lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h | 27 | ||||
-rw-r--r-- | lib/Target/AArch64/SVEInstrFormats.td | 79 | ||||
-rw-r--r-- | test/MC/AArch64/SVE/dupm-diagnostics.s | 39 | ||||
-rw-r--r-- | test/MC/AArch64/SVE/dupm.s | 68 | ||||
-rw-r--r-- | test/MC/AArch64/SVE/mov-diagnostics.s | 48 | ||||
-rw-r--r-- | test/MC/AArch64/SVE/mov.s | 36 |
11 files changed, 304 insertions, 25 deletions
diff --git a/lib/Target/AArch64/AArch64SVEInstrInfo.td b/lib/Target/AArch64/AArch64SVEInstrInfo.td index 513b4f7a257..3207be74968 100644 --- a/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -37,6 +37,7 @@ let Predicates = [HasSVE] in { // Splat immediate (unpredicated) defm DUP_ZI : sve_int_dup_imm<"dup">; + defm DUPM_ZI : sve_int_dup_mask_imm<"dupm">; // continuous load with reg+immediate defm LD1B_IMM : sve_mem_cld_si<0b0000, "ld1b", Z_b, ZPR8>; diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 77aff4fccc8..031de490885 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -752,6 +752,12 @@ public: return DiagnosticPredicateTy::NearMatch; } + template <typename T> DiagnosticPredicate isSVEPreferredLogicalImm() const { + if (isLogicalImm<T>() && !isSVECpyImm<T>()) + return DiagnosticPredicateTy::Match; + return DiagnosticPredicateTy::NoMatch; + } + bool isCondCode() const { return Kind == k_CondCode; } bool isSIMDImmType10() const { diff --git a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index ecb51cf695f..f9c9c56cd60 100644 --- a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1759,7 +1759,8 @@ static DecodeStatus DecodeSVELogicalImmInstruction(llvm::MCInst &Inst, // The same (tied) operand is added twice to the instruction. DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder); - DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder); + if (Inst.getOpcode() != AArch64::DUPM_ZI) + DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder); Inst.addOperand(MCOperand::createImm(imm)); return Success; } diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index 1f3dc0c39b4..67584d1cbfe 100644 --- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1480,3 +1480,22 @@ void AArch64InstPrinter::printImm8OptLsl(const MCInst *MI, unsigned OpNum, printImmSVE(Val, O); } + +template <typename T> +void AArch64InstPrinter::printSVELogicalImm(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + typedef typename std::make_signed<T>::type SignedT; + typedef typename std::make_unsigned<T>::type UnsignedT; + + uint64_t Val = MI->getOperand(OpNum).getImm(); + UnsignedT PrintVal = AArch64_AM::decodeLogicalImmediate(Val, 64); + + // Prefer the default format for 16bit values, hex otherwise. + if ((int16_t)PrintVal == (SignedT)PrintVal) + printImmSVE((T)PrintVal, O); + else if ((uint16_t)PrintVal == PrintVal) + printImmSVE(PrintVal, O); + else + O << '#' << formatHex((uint64_t)PrintVal); +} diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h index 4c8bf4fc826..ca108308c71 100644 --- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -172,6 +172,9 @@ protected: template <typename T> void printImm8OptLsl(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + template <typename T> + void printSVELogicalImm(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> diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h b/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h index 177ead2e28b..16c3a037455 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h +++ b/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h @@ -782,6 +782,33 @@ static inline bool isSVEAddSubImm(int64_t Imm) { return uint8_t(Imm) == Imm || (!IsInt8t && uint16_t(Imm & ~0xff) == Imm); } +/// Return true if Imm is valid for DUPM and has no single CPY/DUP equivalent. +static inline bool isSVEMoveMaskPreferredLogicalImmediate(int64_t Imm) { + union { + int64_t D; + int32_t S[2]; + int16_t H[4]; + int8_t B[8]; + } Vec = { Imm }; + + if (isSVECpyImm<int64_t>(Vec.D)) + return false; + + if (isSVEMaskOfIdenticalElements<int32_t>(Imm) && + isSVECpyImm<int32_t>(Vec.S[0])) + return false; + + if (isSVEMaskOfIdenticalElements<int16_t>(Imm) && + isSVECpyImm<int16_t>(Vec.H[0])) + return false; + + if (isSVEMaskOfIdenticalElements<int8_t>(Imm) && + isSVECpyImm<int8_t>(Vec.B[0])) + return false; + + return isLogicalImmediate(Vec.D, 64); +} + inline static bool isAnyMOVZMovAlias(uint64_t Value, int RegWidth) { for (int Shift = 0; Shift <= RegWidth - 16; Shift += 16) if ((Value & ~(0xffffULL << Shift)) == 0) diff --git a/lib/Target/AArch64/SVEInstrFormats.td b/lib/Target/AArch64/SVEInstrFormats.td index 7f0dbdc89d5..8794522c2c6 100644 --- a/lib/Target/AArch64/SVEInstrFormats.td +++ b/lib/Target/AArch64/SVEInstrFormats.td @@ -84,6 +84,51 @@ def sve_logical_imm32 : Operand<i64> { }]; } +class SVEPreferredLogicalImmOperand<int Width> : AsmOperandClass { + let Name = "SVEPreferredLogicalImm" # Width; + let PredicateMethod = "isSVEPreferredLogicalImm<int" # Width # "_t>"; + let RenderMethod = "addLogicalImmOperands<int" # Width # "_t>"; +} + +def sve_preferred_logical_imm16 : Operand<i64> { + let ParserMatchClass = SVEPreferredLogicalImmOperand<16>; + let PrintMethod = "printSVELogicalImm<int16_t>"; + + let MCOperandPredicate = [{ + if (!MCOp.isImm()) + return false; + int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64); + return AArch64_AM::isSVEMaskOfIdenticalElements<int16_t>(Val) && + AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val); + }]; +} + +def sve_preferred_logical_imm32 : Operand<i64> { + let ParserMatchClass = SVEPreferredLogicalImmOperand<32>; + let PrintMethod = "printSVELogicalImm<int32_t>"; + + let MCOperandPredicate = [{ + if (!MCOp.isImm()) + return false; + int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64); + return AArch64_AM::isSVEMaskOfIdenticalElements<int32_t>(Val) && + AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val); + }]; +} + +def sve_preferred_logical_imm64 : Operand<i64> { + let ParserMatchClass = SVEPreferredLogicalImmOperand<64>; + let PrintMethod = "printSVELogicalImm<int64_t>"; + + let MCOperandPredicate = [{ + if (!MCOp.isImm()) + return false; + int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64); + return AArch64_AM::isSVEMaskOfIdenticalElements<int64_t>(Val) && + AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val); + }]; +} + class SVELogicalImmNotOperand<int Width> : AsmOperandClass { let Name = "SVELogicalImm" # Width # "Not"; let DiagnosticType = "LogicalSecondSource"; @@ -279,6 +324,40 @@ multiclass sve_int_log_imm<bits<2> opc, string asm, string alias> { (!cast<Instruction>(NAME) ZPR64:$Zdn, logical_imm64_not:$imm), 0>; } +class sve_int_dup_mask_imm<string asm> +: I<(outs ZPR64:$Zd), (ins logical_imm64:$imms), + asm, "\t$Zd, $imms", + "", + []>, Sched<[]> { + bits<5> Zd; + bits<13> imms; + let Inst{31-18} = 0b00000101110000; + let Inst{17-5} = imms; + let Inst{4-0} = Zd; + + let isReMaterializable = 1; + let DecoderMethod = "DecodeSVELogicalImmInstruction"; +} + +multiclass sve_int_dup_mask_imm<string asm> { + def NAME : sve_int_dup_mask_imm<asm>; + + def : InstAlias<"dupm $Zd, $imm", + (!cast<Instruction>(NAME) ZPR8:$Zd, sve_logical_imm8:$imm), 4>; + def : InstAlias<"dupm $Zd, $imm", + (!cast<Instruction>(NAME) ZPR16:$Zd, sve_logical_imm16:$imm), 3>; + def : InstAlias<"dupm $Zd, $imm", + (!cast<Instruction>(NAME) ZPR32:$Zd, sve_logical_imm32:$imm), 2>; + + // All Zd.b forms have a CPY/DUP equivalent, hence no byte alias here. + def : InstAlias<"mov $Zd, $imm", + (!cast<Instruction>(NAME) ZPR16:$Zd, sve_preferred_logical_imm16:$imm), 7>; + def : InstAlias<"mov $Zd, $imm", + (!cast<Instruction>(NAME) ZPR32:$Zd, sve_preferred_logical_imm32:$imm), 6>; + def : InstAlias<"mov $Zd, $imm", + (!cast<Instruction>(NAME) ZPR64:$Zd, sve_preferred_logical_imm64:$imm), 5>; +} + //===----------------------------------------------------------------------===// // SVE Integer Arithmetic - Unpredicated Group. //===----------------------------------------------------------------------===// diff --git a/test/MC/AArch64/SVE/dupm-diagnostics.s b/test/MC/AArch64/SVE/dupm-diagnostics.s new file mode 100644 index 00000000000..cb2277a1f87 --- /dev/null +++ b/test/MC/AArch64/SVE/dupm-diagnostics.s @@ -0,0 +1,39 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Immediate not compatible with encode/decode function. + +dupm z5.b, #0xfa +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or logical immediate +// CHECK-NEXT: dupm z5.b, #0xfa +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dupm z5.b, #0xfff9 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or logical immediate +// CHECK-NEXT: dupm z5.b, #0xfff9 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dupm z5.h, #0xfffa +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or logical immediate +// CHECK-NEXT: dupm z5.h, #0xfffa +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dupm z5.h, #0xfffffff9 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or logical immediate +// CHECK-NEXT: dupm z5.h, #0xfffffff9 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dupm z5.s, #0xfffffffa +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or logical immediate +// CHECK-NEXT: dupm z5.s, #0xfffffffa +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dupm z5.s, #0xffffffffffffff9 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or logical immediate +// CHECK-NEXT: dupm z5.s, #0xffffffffffffff9 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dupm z15.d, #0xfffffffffffffffa +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or logical immediate +// CHECK-NEXT: dupm z15.d, #0xfffffffffffffffa +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/dupm.s b/test/MC/AArch64/SVE/dupm.s new file mode 100644 index 00000000000..9bfa53a5729 --- /dev/null +++ b/test/MC/AArch64/SVE/dupm.s @@ -0,0 +1,68 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +dupm z5.b, #0xf9 +// CHECK-INST: dupm z5.b, #0xf9 +// CHECK-ENCODING: [0xa5,0x2e,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: a5 2e c0 05 <unknown> + +dupm z5.h, #0xf9f9 +// CHECK-INST: dupm z5.b, #0xf9 +// CHECK-ENCODING: [0xa5,0x2e,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: a5 2e c0 05 <unknown> + +dupm z5.s, #0xf9f9f9f9 +// CHECK-INST: dupm z5.b, #0xf9 +// CHECK-ENCODING: [0xa5,0x2e,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: a5 2e c0 05 <unknown> + +dupm z5.d, #0xf9f9f9f9f9f9f9f9 +// CHECK-INST: dupm z5.b, #0xf9 +// CHECK-ENCODING: [0xa5,0x2e,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: a5 2e c0 05 <unknown> + +dupm z23.h, #0xfff9 +// CHECK-INST: dupm z23.h, #0xfff9 +// CHECK-ENCODING: [0xb7,0x6d,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: b7 6d c0 05 <unknown> + +dupm z23.s, #0xfff9fff9 +// CHECK-INST: dupm z23.h, #0xfff9 +// CHECK-ENCODING: [0xb7,0x6d,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: b7 6d c0 05 <unknown> + +dupm z23.d, #0xfff9fff9fff9fff9 +// CHECK-INST: dupm z23.h, #0xfff9 +// CHECK-ENCODING: [0xb7,0x6d,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: b7 6d c0 05 <unknown> + +dupm z0.s, #0xfffffff9 +// CHECK-INST: dupm z0.s, #0xfffffff9 +// CHECK-ENCODING: [0xa0,0xeb,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: a0 eb c0 05 <unknown> + +dupm z0.d, #0xfffffff9fffffff9 +// CHECK-INST: dupm z0.s, #0xfffffff9 +// CHECK-ENCODING: [0xa0,0xeb,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: a0 eb c0 05 <unknown> + +dupm z0.d, #0xfffffffffffffff9 +// CHECK-INST: dupm z0.d, #0xfffffffffffffff9 +// CHECK-ENCODING: [0xa0,0xef,0xc3,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: a0 ef c3 05 <unknown> diff --git a/test/MC/AArch64/SVE/mov-diagnostics.s b/test/MC/AArch64/SVE/mov-diagnostics.s index 89f67c9f89a..92030054eaa 100644 --- a/test/MC/AArch64/SVE/mov-diagnostics.s +++ b/test/MC/AArch64/SVE/mov-diagnostics.s @@ -85,11 +85,6 @@ mov z0.h, #32513 // 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 @@ -100,11 +95,6 @@ mov z0.s, #-33024 // 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 @@ -115,11 +105,6 @@ mov z0.s, #32513 // 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 @@ -130,11 +115,6 @@ mov z0.d, #-33024 // 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 @@ -145,12 +125,32 @@ mov z0.d, #32513 // CHECK-NEXT: mov z0.d, #32513 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: -mov z0.d, #32768 +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, #32768 +// CHECK-NEXT: mov z0.d, #128, lsl #8 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: -mov z0.d, #128, lsl #8 +mov z5.b, #0xfff9 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 255] with a shift amount of 0 +// CHECK-NEXT: mov z5.b, #0xfff9 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z5.h, #0xfffa // 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-NEXT: mov z5.h, #0xfffa +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z5.h, #0xfffffff9 +// 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 z5.h, #0xfffffff9 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z5.s, #0xfffffffa +// 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 z5.s, #0xfffffffa +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +mov z5.s, #0xffffffffffffff9 +// 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 z5.s, #0xffffffffffffff9 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/mov.s b/test/MC/AArch64/SVE/mov.s index e3d9a7b144c..d2b9b362796 100644 --- a/test/MC/AArch64/SVE/mov.s +++ b/test/MC/AArch64/SVE/mov.s @@ -192,3 +192,39 @@ mov z21.d, #32512 // CHECK-ENCODING: [0xf5,0xef,0xf8,0x25] // CHECK-ERROR: instruction requires: sve // CHECK-UNKNOWN: f5 ef f8 25 <unknown> + +mov z0.h, #32768 +// CHECK-INST: dupm z0.h, #0x8000 +// CHECK-ENCODING: [0x00,0x0c,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 0c c0 05 <unknown> + +mov z0.s, #-32769 +// CHECK-INST: mov z0.s, #0xffff7fff +// CHECK-ENCODING: [0xc0,0x83,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: c0 83 c0 05 <unknown> + +mov z0.s, #32768 +// CHECK-INST: mov z0.s, #32768 +// CHECK-ENCODING: [0x00,0x88,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 88 c0 05 <unknown> + +mov z0.d, #-32769 +// CHECK-INST: mov z0.d, #0xffffffffffff7fff +// CHECK-ENCODING: [0xc0,0x87,0xc3,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: c0 87 c3 05 <unknown> + +mov z0.d, #32768 +// CHECK-INST: mov z0.d, #32768 +// CHECK-ENCODING: [0x00,0x88,0xc3,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 88 c3 05 <unknown> + +mov z0.d, #0xe0000000000003ff +// CHECK-INST: mov z0.d, #0xe0000000000003ff +// CHECK-ENCODING: [0x80,0x19,0xc2,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 80 19 c2 05 <unknown> |