[mips][ias] Range check uimm2 operands and fix a bug this revealed.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Fri, 6 Nov 2015 12:22:31 +0000 (12:22 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Fri, 6 Nov 2015 12:22:31 +0000 (12:22 +0000)
Summary:
The bug was that the MIPS32R6/MIPS64R6/microMIPS32R6 versions of LSA and DLSA
(unlike the MSA version) failed to account for the off-by-one encoding of the
immediate. The range is actually 1..4 rather than 0..3.

Reviewers: vkalintiris

Subscribers: atanasyan, dsanders, llvm-commits

Differential Revision: http://reviews.llvm.org/D14015

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252295 91177308-0d34-0410-b5e6-96231b3b80d8

23 files changed:
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/Disassembler/MipsDisassembler.cpp
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
lib/Target/Mips/MicroMips32r6InstrInfo.td
lib/Target/Mips/Mips32r6InstrInfo.td
lib/Target/Mips/Mips64r6InstrInfo.td
lib/Target/Mips/MipsInstrInfo.td
lib/Target/Mips/MipsMSAInstrInfo.td
test/MC/Disassembler/Mips/micromips32r6/valid.txt
test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt
test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt
test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt
test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt
test/MC/Mips/micromips32r6/invalid.s
test/MC/Mips/micromips32r6/valid.s
test/MC/Mips/micromips64r6/invalid.s
test/MC/Mips/mips32r6/invalid.s
test/MC/Mips/mips32r6/valid.s
test/MC/Mips/mips64r6/invalid.s
test/MC/Mips/mips64r6/valid.s
test/MC/Mips/msa/invalid-64.s
test/MC/Mips/msa/invalid.s

index 09ae6a5..aea022a 100644 (file)
@@ -387,7 +387,6 @@ public:
 #define GET_OPERAND_DIAGNOSTIC_TYPES
 #include "MipsGenAsmMatcher.inc"
 #undef GET_OPERAND_DIAGNOSTIC_TYPES
-
   };
 
   MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
@@ -894,10 +893,12 @@ public:
     Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
   }
 
-  template <unsigned Bits>
+  template <unsigned Bits, int Offset = 0>
   void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
-    uint64_t Imm = getConstantImm() & ((1 << Bits) - 1);
+    uint64_t Imm = getConstantImm() - Offset;
+    Imm &= (1 << Bits) - 1;
+    Imm += Offset;
     Inst.addOperand(MCOperand::createImm(Imm));
   }
 
@@ -963,6 +964,9 @@ public:
   bool isConstantImmz() const {
     return isConstantImm() && getConstantImm() == 0;
   }
+  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
+    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
+  }
   template <unsigned Bits> bool isUImm() const {
     return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
   }
@@ -3296,6 +3300,12 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return Error(IDLoc, "source and destination must be different");
   case Match_Immz:
     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
+  case Match_UImm2_0:
+    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+                 "expected 2-bit unsigned immediate");
+  case Match_UImm2_1:
+    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+                 "expected immediate in range 1 .. 4");
   }
 
   llvm_unreachable("Implement any new match types added!");
index 121b49c..6332e1d 100644 (file)
@@ -380,12 +380,9 @@ static DecodeStatus DecodeSimm16(MCInst &Inst,
                                  uint64_t Address,
                                  const void *Decoder);
 
-// Decode the immediate field of an LSA instruction which
-// is off by one.
-static DecodeStatus DecodeLSAImm(MCInst &Inst,
-                                 unsigned Insn,
-                                 uint64_t Address,
-                                 const void *Decoder);
+template <unsigned Bits, int Offset>
+static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
+                                         uint64_t Address, const void *Decoder);
 
 static DecodeStatus DecodeInsSize(MCInst &Inst,
                                   unsigned Insn,
@@ -1908,12 +1905,12 @@ static DecodeStatus DecodeSimm16(MCInst &Inst,
   return MCDisassembler::Success;
 }
 
-static DecodeStatus DecodeLSAImm(MCInst &Inst,
-                                 unsigned Insn,
-                                 uint64_t Address,
-                                 const void *Decoder) {
-  // We add one to the immediate field as it was encoded as 'imm - 1'.
-  Inst.addOperand(MCOperand::createImm(Insn + 1));
+template <unsigned Bits, int Offset>
+static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
+                                         uint64_t Address,
+                                         const void *Decoder) {
+  Value &= ((1 << Bits) - 1);
+  Inst.addOperand(MCOperand::createImm(Value + Offset));
   return MCDisassembler::Success;
 }
 
index bd6afcb..861049f 100644 (file)
@@ -869,13 +869,15 @@ MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
   return Position + Size - 1;
 }
 
+template <unsigned Bits, int Offset>
 unsigned
-MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
-                                     SmallVectorImpl<MCFixup> &Fixups,
-                                     const MCSubtargetInfo &STI) const {
+MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
+                                             SmallVectorImpl<MCFixup> &Fixups,
+                                             const MCSubtargetInfo &STI) const {
   assert(MI.getOperand(OpNo).isImm());
-  // The immediate is encoded as 'immediate - 1'.
-  return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1;
+  unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
+  Value -= Offset;
+  return Value;
 }
 
 unsigned
index 56f286a..c2f4b6a 100644 (file)
@@ -191,10 +191,11 @@ public:
                               SmallVectorImpl<MCFixup> &Fixups,
                               const MCSubtargetInfo &STI) const;
 
-  // getLSAImmEncoding - Return binary encoding of LSA immediate.
-  unsigned getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
-                             SmallVectorImpl<MCFixup> &Fixups,
-                             const MCSubtargetInfo &STI) const;
+  /// Subtract Offset then encode as a N-bit unsigned integer.
+  template <unsigned Bits, int Offset>
+  unsigned getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
+                                     SmallVectorImpl<MCFixup> &Fixups,
+                                     const MCSubtargetInfo &STI) const;
 
   unsigned getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
                                  SmallVectorImpl<MCFixup> &Fixups,
index f33ccf2..572ba78 100644 (file)
@@ -426,7 +426,7 @@ class LSA_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
   list<dag> Pattern = [];
 }
 
-class LSA_MMR6_DESC : LSA_MMR6_DESC_BASE<"lsa", GPR32Opnd, uimm2>;
+class LSA_MMR6_DESC : LSA_MMR6_DESC_BASE<"lsa", GPR32Opnd, uimm2_plus1>;
 
 class PCREL_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
                            Operand ImmOpnd> : MMR6Arch<instr_asm> {
index 8a6ae21..9dd4d1e 100644 (file)
@@ -597,7 +597,7 @@ class LSA_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
   list<dag> Pattern = [];
 }
 
-class LSA_R6_DESC : LSA_R6_DESC_BASE<"lsa", GPR32Opnd, uimm2>;
+class LSA_R6_DESC : LSA_R6_DESC_BASE<"lsa", GPR32Opnd, uimm2_plus1>;
 
 class LL_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
   dag OutOperandList = (outs GPROpnd:$rt);
index 3102849..6f34dbe 100644 (file)
@@ -62,7 +62,7 @@ class DCLO_R6_DESC : CLO_R6_DESC_BASE<"dclo", GPR64Opnd>;
 class DCLZ_R6_DESC : CLZ_R6_DESC_BASE<"dclz", GPR64Opnd>;
 class DDIV_DESC    : DIVMOD_DESC_BASE<"ddiv", GPR64Opnd, sdiv>;
 class DDIVU_DESC   : DIVMOD_DESC_BASE<"ddivu", GPR64Opnd, udiv>;
-class DLSA_R6_DESC : LSA_R6_DESC_BASE<"dlsa", GPR64Opnd, uimm2>;
+class DLSA_R6_DESC : LSA_R6_DESC_BASE<"dlsa", GPR64Opnd, uimm2_plus1>;
 class DMOD_DESC    : DIVMOD_DESC_BASE<"dmod", GPR64Opnd, srem>;
 class DMODU_DESC   : DIVMOD_DESC_BASE<"dmodu", GPR64Opnd, urem>;
 class DMUH_DESC    : MUL_R6_DESC_BASE<"dmuh", GPR64Opnd, mulhs>;
index 0a32967..c0e62a5 100644 (file)
@@ -381,11 +381,24 @@ include "MipsInstrFormats.td"
 // Mips Operand, Complex Patterns and Transformations Definitions.
 //===----------------------------------------------------------------------===//
 
+class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
+                                  int Offset = 0> : AsmOperandClass {
+  let Name = "ConstantUImm" # Bits # "_" # Offset;
+  let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
+  let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
+  let SuperClasses = Supers;
+  let DiagnosticType = "UImm" # Bits # "_" # Offset;
+}
+
+def ConstantUImm2Plus1AsmOperandClass
+    : ConstantUImmAsmOperandClass<2, [], 1>;
+def ConstantUImm2AsmOperandClass
+    : ConstantUImmAsmOperandClass<2>;
 def ConstantImmzAsmOperandClass : AsmOperandClass {
   let Name = "ConstantImmz";
   let RenderMethod = "addConstantUImmOperands<1>";
   let PredicateMethod = "isConstantImmz";
-  let SuperClasses = [];
+  let SuperClasses = [ConstantUImm2AsmOperandClass];
   let DiagnosticType = "Immz";
 }
 
@@ -461,9 +474,19 @@ def uimmz       : Operand<i32> {
   let ParserMatchClass = ConstantImmzAsmOperandClass;
 }
 
-// Unsigned Operand
-def uimm2 : Operand<i32> {
+// Unsigned Operands
+foreach I = {2} in
+  def uimm # I : Operand<i32> {
+    let PrintMethod = "printUnsignedImm";
+    let ParserMatchClass =
+        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
+  }
+
+def uimm2_plus1 : Operand<i32> {
   let PrintMethod = "printUnsignedImm";
+  let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
+  let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
+  let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
 }
 
 def uimm3 : Operand<i32> {
index 64bae3b..f3e0849 100644 (file)
@@ -70,21 +70,6 @@ def immZExt6Ptr : ImmLeaf<iPTR, [{return isUInt<6>(Imm);}]>;
 
 // Operands
 
-// The immediate of an LSA instruction needs special handling
-// as the encoded value should be subtracted by one.
-def uimm2LSAAsmOperand : AsmOperandClass {
-  let Name = "LSAImm";
-  let ParserMethod = "parseLSAImm";
-  let RenderMethod = "addImmOperands";
-}
-
-def LSAImm : Operand<i32> {
-  let PrintMethod = "printUnsignedImm";
-  let EncoderMethod = "getLSAImmEncoding";
-  let DecoderMethod = "DecodeLSAImm";
-  let ParserMatchClass = uimm2LSAAsmOperand;
-}
-
 def uimm4 : Operand<i32> {
   let PrintMethod = "printUnsignedImm8";
 }
@@ -2380,7 +2365,7 @@ class LSA_DESC_BASE<string instr_asm, RegisterOperand RORD,
                     RegisterOperand RORS = RORD, RegisterOperand RORT = RORD,
                     InstrItinClass itin = NoItinerary > {
   dag OutOperandList = (outs RORD:$rd);
-  dag InOperandList = (ins RORS:$rs, RORT:$rt, LSAImm:$sa);
+  dag InOperandList = (ins RORS:$rs, RORT:$rt, uimm2_plus1:$sa);
   string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt, $sa");
   list<dag> Pattern = [(set RORD:$rd, (add RORT:$rt,
                                                 (shl RORS:$rs,
index 41a8f77..8a65e01 100644 (file)
@@ -63,7 +63,7 @@
 0x80 0x05 0x01 0x00 # CHECK: jialc $5, 256
 0xa0 0x05 0x01 0x00 # CHECK: jic $5, 256
 0x78 0x48 0x00 0x43 # CHECK: lwpc $2, 268
-0x00 0x43 0x26 0x0f # CHECK: lsa $2, $3, $4, 3
+0x00 0x43 0x26 0x0f # CHECK: lsa $2, $3, $4, 4
 0x00 0xa4 0x19 0x58 # CHECK: mod $3, $4, $5
 0x00 0xa4 0x19 0xd8 # CHECK: modu $3, $4, $5
 0x00 0xa4 0x18 0x18 # CHECK: mul $3, $4, $5
index 94dc3a2..4164988 100644 (file)
@@ -80,7 +80,7 @@
 0x9b 0x10 0x64 0x00 # CHECK: divu $2, $3, $4
 0x20 0x60 0x6e 0x41 # CHECK: ei $14
 0x20 0x60 0x60 0x41 # CHECK: ei
-0xc5 0x10 0x64 0x00 # CHECK: lsa $2, $3, $4, 3
+0xc5 0x10 0x64 0x00 # CHECK: lsa $2, $3, $4, 4
 0x43 0x00 0x48 0xec # CHECK: lwpc $2, 268
 0x43 0x00 0x50 0xec # CHECK: lwupc $2, 268
 0x01 0x78 0x08 0x40 # CHECK: mfc0 $8, $15, 1
index 2791b7a..6af02fc 100644 (file)
@@ -12,7 +12,7 @@
 0x00 0x64 0x10 0x99 # CHECK: mulu $2, $3, $4
 0x00 0x64 0x10 0x9a # CHECK: div $2, $3, $4
 0x00 0x64 0x10 0x9b # CHECK: divu $2, $3, $4
-0x00 0x64 0x10 0xc5 # CHECK: lsa $2, $3, $4, 3
+0x00 0x64 0x10 0xc5 # CHECK: lsa $2, $3, $4, 4
 0x00 0x64 0x10 0xd8 # CHECK: muh $2, $3, $4
 0x00 0x64 0x10 0xd9 # CHECK: muhu $2, $3, $4
 0x00 0x64 0x10 0xda # CHECK: mod $2, $3, $4
index b2bbc64..08f5e04 100644 (file)
@@ -91,7 +91,7 @@
 0x00 0x60 0x7e 0x41 # CHECK: di $fp
 0x9a 0x10 0x64 0x00 # CHECK: div $2, $3, $4
 0x9b 0x10 0x64 0x00 # CHECK: divu $2, $3, $4
-0xd5 0x10 0x64 0x00 # CHECK: dlsa $2, $3, $4, 3
+0xd5 0x10 0x64 0x00 # CHECK: dlsa $2, $3, $4, 4
 0x00 0x50 0x38 0x40 # CHECK: dmfc0 $24, $10, 0
 0xde 0x10 0x64 0x00 # CHECK: dmod $2, $3, $4
 0xdf 0x10 0x64 0x00 # CHECK: dmodu $2, $3, $4
 0x48 0x3c 0x58 0xec # CHECK: ldpc $2, 123456
 0xb6 0xb3 0x42 0x7e # CHECK: ll $2, -153($18)
 0x37 0x38 0xe0 0x7f # CHECK: lld $zero, 112($ra)
-0xc5 0x10 0x64 0x00 # CHECK: lsa $2, $3, $4, 3
+0xc5 0x10 0x64 0x00 # CHECK: lsa $2, $3, $4, 4
 0xb7 0x34 0x52 0x49 # CHECK: lwc2 $18, -841($6)
 0x43 0x00 0x48 0xec # CHECK: lwpc $2, 268
 0x43 0x00 0x50 0xec # CHECK: lwupc $2, 268
index e6378d2..7fa27a7 100644 (file)
@@ -18,8 +18,8 @@
 0x00 0x64 0x10 0x9d # CHECK: dmulu $2, $3, $4
 0x00 0x64 0x10 0x9e # CHECK: ddiv $2, $3, $4
 0x00 0x64 0x10 0x9f # CHECK: ddivu $2, $3, $4
-0x00 0x64 0x10 0xc5 # CHECK: lsa $2, $3, $4, 3
-0x00 0x64 0x10 0xd5 # CHECK: dlsa $2, $3, $4, 3
+0x00 0x64 0x10 0xc5 # CHECK: lsa $2, $3, $4, 4
+0x00 0x64 0x10 0xd5 # CHECK: dlsa $2, $3, $4, 4
 0x00 0x64 0x10 0xd8 # CHECK: muh $2, $3, $4
 0x00 0x64 0x10 0xd9 # CHECK: muhu $2, $3, $4
 0x00 0x64 0x10 0xda # CHECK: mod $2, $3, $4
index d645899..039855e 100644 (file)
@@ -8,6 +8,8 @@
   addiur2 $6, $7, 10       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   addius5 $7, 9            # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   addiusp 1032             # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
+  align $4, $2, $3, -1     # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate
+  align $4, $2, $3, 4      # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate
   beqzc16 $9, 20           # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   beqzc16 $6, 31           # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address
   beqzc16 $6, 130          # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range
@@ -28,6 +30,8 @@
   lhu16 $3, 64($16)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   lhu16 $3, 64($16)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   lhu16 $16, 4($9)         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  lsa   $4, $2, $3, 0      # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
+  lsa   $4, $2, $3, 5      # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
   lw16  $9, 8($17)         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   lw16  $4, 68($17)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   lw16  $4, 68($17)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
index f0885ab..a1b1a50 100644 (file)
@@ -52,7 +52,7 @@
   jic   $5, 256            # CHECK: jic $5, 256         # encoding: [0xa0,0x05,0x01,0x00]
   jrc16 $9                 # CHECK: jrc16 $9            # encoding: [0x45,0x23]
   jrcaddiusp 20            # CHECK: jrcaddiusp 20       # encoding: [0x44,0xb3]
-  lsa $2, $3, $4, 3        # CHECK: lsa  $2, $3, $4, 3  # encoding: [0x00,0x43,0x26,0x0f]
+  lsa $2, $3, $4, 3        # CHECK: lsa  $2, $3, $4, 3  # encoding: [0x00,0x43,0x24,0x0f]
   lwpc    $2,268           # CHECK: lwpc $2, 268        # encoding: [0x78,0x48,0x00,0x43]
   mod $3, $4, $5           # CHECK: mod $3, $4, $5      # encoding: [0x00,0xa4,0x19,0x58]
   modu $3, $4, $5          # CHECK: modu $3, $4, $5     # encoding: [0x00,0xa4,0x19,0xd8]
index 59e7cd6..695bab3 100644 (file)
@@ -8,6 +8,8 @@
   addiur2 $6, $7, 10       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   addius5 $7, 9            # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   addiusp 1032             # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
+  align $4, $2, $3, -1     # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate
+  align $4, $2, $3, 4      # CHECK: :[[@LINE]]:21: error: expected 2-bit unsigned immediate
   beqzc16 $9, 20           # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   beqzc16 $6, 31           # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address
   beqzc16 $6, 130          # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range
@@ -22,6 +24,8 @@
   lhu16 $3, 64($16)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   lhu16 $3, 64($16)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   lhu16 $16, 4($9)         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  lsa   $4, $2, $3, 0      # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
+  lsa   $4, $2, $3, 5      # CHECK: :[[@LINE]]:21: error: expected immediate in range 1 .. 4
   lw16  $9, 8($17)         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   lw16  $4, 68($17)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   lw16  $4, 68($17)        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
index d10a945..c96d2c6 100644 (file)
@@ -8,6 +8,8 @@
 local_label:
         .set noreorder
         .set noat
+        align   $4, $2, $3, -1    # CHECK: :[[@LINE]]:29: error: expected 2-bit unsigned immediate
+        align   $4, $2, $3, 4     # CHECK: :[[@LINE]]:29: error: expected 2-bit unsigned immediate
         jalr.hb $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different
         jalr.hb $31, $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different
         ldc2    $8,-21181($at)   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
@@ -26,3 +28,5 @@ local_label:
         bgeul $7, $8, local_label  # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         bgtl  $7, $8, local_label  # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         bgtul $7, $8, local_label  # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
+        lsa     $2, $3, $4, 0     # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4
+        lsa     $2, $3, $4, 5     # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4
index a000e8b..226acd9 100644 (file)
@@ -107,7 +107,7 @@ a:
         eretnc                   # CHECK: eretnc           # encoding: [0x42,0x00,0x00,0x58]
         jialc   $5, 256          # CHECK: jialc $5, 256    # encoding: [0xf8,0x05,0x01,0x00]
         jic     $5, 256          # CHECK: jic $5, 256      # encoding: [0xd8,0x05,0x01,0x00]
-        lsa     $2, $3, $4, 3    # CHECK: lsa  $2, $3, $4, 3 # encoding: [0x00,0x64,0x10,0xc5]
+        lsa     $2, $3, $4, 3    # CHECK: lsa  $2, $3, $4, 3 # encoding: [0x00,0x64,0x10,0x85]
         lwpc    $2,268           # CHECK: lwpc $2, 268     # encoding: [0xec,0x48,0x00,0x43]
         lwupc   $2,268           # CHECK: lwupc $2, 268    # encoding: [0xec,0x50,0x00,0x43]
         mfc0    $8,$15,1         # CHECK: mfc0 $8, $15, 1  # encoding: [0x40,0x08,0x78,0x01]
index 24a7667..63f08dd 100644 (file)
@@ -8,6 +8,8 @@
 local_label:
         .set noreorder
        .set noat
+        align   $4, $2, $3, -1    # CHECK: :[[@LINE]]:29: error: expected 2-bit unsigned immediate
+        align   $4, $2, $3, 4     # CHECK: :[[@LINE]]:29: error: expected 2-bit unsigned immediate
         jalr.hb $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different
         jalr.hb $31, $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different
         ldc2    $8,-21181($at)   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
@@ -24,3 +26,7 @@ local_label:
         bgeul $7, $8, local_label  # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         bgtl  $7, $8, local_label  # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         bgtul $7, $8, local_label  # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
+        dlsa    $2, $3, $4, 0     # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4
+        dlsa    $2, $3, $4, 5     # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4
+        lsa     $2, $3, $4, 0     # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4
+        lsa     $2, $3, $4, 5     # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4
index 8fd4c65..0b4b6b1 100644 (file)
@@ -116,7 +116,7 @@ a:
         di      $s8              # CHECK: di  $fp          # encoding: [0x41,0x7e,0x60,0x00]
         div     $2,$3,$4         # CHECK: div $2, $3, $4   # encoding: [0x00,0x64,0x10,0x9a]
         divu    $2,$3,$4         # CHECK: divu $2, $3, $4  # encoding: [0x00,0x64,0x10,0x9b]
-        dlsa    $2, $3, $4, 3    # CHECK: dlsa $2, $3, $4, 3 # encoding: [0x00,0x64,0x10,0xd5]
+        dlsa    $2, $3, $4, 3    # CHECK: dlsa $2, $3, $4, 3 # encoding: [0x00,0x64,0x10,0x95]
         dmfc0   $10, $16, 2      # CHECK: dmfc0 $10, $16, 2  # encoding: [0x40,0x2a,0x80,0x02]
         dmod    $2,$3,$4         # CHECK: dmod $2, $3, $4  # encoding: [0x00,0x64,0x10,0xde]
         dmodu   $2,$3,$4         # CHECK: dmodu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xdf]
@@ -147,7 +147,7 @@ a:
         ldpc    $2,123456        # CHECK: ldpc $2, 123456  # encoding: [0xec,0x58,0x3c,0x48]
         ll      $v0,-153($s2)    # CHECK: ll $2, -153($18)       # encoding: [0x7e,0x42,0xb3,0xb6]
         lld     $zero,112($ra)   # CHECK: lld $zero, 112($ra)    # encoding: [0x7f,0xe0,0x38,0x37]
-        lsa     $2, $3, $4, 3    # CHECK: lsa  $2, $3, $4, 3 # encoding: [0x00,0x64,0x10,0xc5]
+        lsa     $2, $3, $4, 3    # CHECK: lsa  $2, $3, $4, 3     # encoding: [0x00,0x64,0x10,0x85]
         lwc2    $18,-841($a2)    # CHECK: lwc2 $18, -841($6)     # encoding: [0x49,0x52,0x34,0xb7]
         lwpc    $2,268           # CHECK: lwpc $2, 268     # encoding: [0xec,0x48,0x00,0x43]
         lwupc   $2,268           # CHECK: lwupc $2, 268    # encoding: [0xec,0x50,0x00,0x43]
index cf1bff5..456ae21 100644 (file)
@@ -1,11 +1,15 @@
 # Instructions that are invalid
 #
-# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+msa \
+# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips64r2 -mattr=+msa \
 # RUN:     -show-encoding 2>%t1
 # RUN: FileCheck %s < %t1
 
     .set noat
+    dlsa    $2, $3, $4, 0   # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 4
+    dlsa    $2, $3, $4, 5   # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 4
     insve.b $w25[3], $w9[1] # CHECK: :[[@LINE]]:26: error: expected '0'
     insve.h $w24[2], $w2[1] # CHECK: :[[@LINE]]:26: error: expected '0'
     insve.w $w0[2], $w13[1] # CHECK: :[[@LINE]]:26: error: expected '0'
     insve.d $w3[0], $w18[1] # CHECK: :[[@LINE]]:26: error: expected '0'
+    lsa     $2, $3, $4, 0   # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 4
+    lsa     $2, $3, $4, 5   # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 4
index cf1bff5..0875efb 100644 (file)
@@ -9,3 +9,5 @@
     insve.h $w24[2], $w2[1] # CHECK: :[[@LINE]]:26: error: expected '0'
     insve.w $w0[2], $w13[1] # CHECK: :[[@LINE]]:26: error: expected '0'
     insve.d $w3[0], $w18[1] # CHECK: :[[@LINE]]:26: error: expected '0'
+    lsa     $2, $3, $4, 0   # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 4
+    lsa     $2, $3, $4, 5   # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 4