]> granicus.if.org Git - llvm/commitdiff
[mips] Implement the 'dext' aliases and it's disassembly alias.
authorSimon Dardis <simon.dardis@imgtec.com>
Thu, 14 Sep 2017 17:27:53 +0000 (17:27 +0000)
committerSimon Dardis <simon.dardis@imgtec.com>
Thu, 14 Sep 2017 17:27:53 +0000 (17:27 +0000)
The other members of the dext family of instructions (dextm, dextu) are
traditionally handled by the assembler selecting the right variant of
'dext' depending on the values of the position and size operands.

When these instructions are disassembled, rather than reporting the
actual instruction, an equivalent aliased form of 'dext' is generated
and is reported. This is to mimic the behaviour of binutils.

Reviewers: slthakur, nitesh.jain, atanasyan

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

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

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/Disassembler/MipsDisassembler.cpp
lib/Target/Mips/MicroMips64r6InstrInfo.td
lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsInstrInfo.td
test/MC/Disassembler/Mips/micromips64r6/valid.txt
test/MC/Mips/micromips64r6/invalid.s
test/MC/Mips/mips64extins.s
test/MC/Mips/mips64r2/invalid.s
test/MC/Mips/mips64r6/invalid.s

index 0714f8cb5224db4f5939ae72b04b6fe03a46d9f2..9bbb430962ecaf605db96993430c2d1a70e8b915 100644 (file)
@@ -465,6 +465,7 @@ public:
     Match_NonZeroOperandForSync,
     Match_RequiresPosSizeRange0_32,
     Match_RequiresPosSizeRange33_64,
+    Match_RequiresPosSizeUImm6,
 #define GET_OPERAND_DIAGNOSTIC_TYPES
 #include "MipsGenAsmMatcher.inc"
 #undef GET_OPERAND_DIAGNOSTIC_TYPES
@@ -4979,28 +4980,50 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
     if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
       return Match_RequiresDifferentOperands;
     return Match_Success;
-   case Mips::DINS:
-   case Mips::DINS_MM64R6: {
-     assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
-            "Operands must be immediates for dins!");
-     const signed Pos = Inst.getOperand(2).getImm();
-     const signed Size = Inst.getOperand(3).getImm();
-     if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
-       return Match_RequiresPosSizeRange0_32;
-     return Match_Success;
-   }
-   case Mips::DINSM:
-   case Mips::DINSM_MM64R6:
-   case Mips::DINSU:
-   case Mips::DINSU_MM64R6: {
-     assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
-            "Operands must be immediates for dinsm/dinsu!");
-     const signed Pos = Inst.getOperand(2).getImm();
-     const signed Size = Inst.getOperand(3).getImm();
-     if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
-       return Match_RequiresPosSizeRange33_64;
-     return Match_Success;
-   }
+  case Mips::DINS:
+  case Mips::DINS_MM64R6: {
+    assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+           "Operands must be immediates for dins!");
+    const signed Pos = Inst.getOperand(2).getImm();
+    const signed Size = Inst.getOperand(3).getImm();
+    if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
+      return Match_RequiresPosSizeRange0_32;
+    return Match_Success;
+  }
+  case Mips::DINSM:
+  case Mips::DINSM_MM64R6:
+  case Mips::DINSU:
+  case Mips::DINSU_MM64R6: {
+    assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+           "Operands must be immediates for dinsm/dinsu!");
+    const signed Pos = Inst.getOperand(2).getImm();
+    const signed Size = Inst.getOperand(3).getImm();
+    if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
+      return Match_RequiresPosSizeRange33_64;
+    return Match_Success;
+  }
+  case Mips::DEXT:
+  case Mips::DEXT_MM64R6: {
+    assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+           "Operands must be immediates for DEXTM!");
+    const signed Pos = Inst.getOperand(2).getImm();
+    const signed Size = Inst.getOperand(3).getImm();
+    if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
+      return Match_RequiresPosSizeUImm6;
+    return Match_Success;
+  }
+  case Mips::DEXTM:
+  case Mips::DEXTU:
+  case Mips::DEXTM_MM64R6:
+  case Mips::DEXTU_MM64R6: {
+    assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+           "Operands must be immediates for dextm/dextu!");
+    const signed Pos = Inst.getOperand(2).getImm();
+    const signed Size = Inst.getOperand(3).getImm();
+    if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
+      return Match_RequiresPosSizeRange33_64;
+    return Match_Success;
+  }
   }
 
   uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
@@ -5199,6 +5222,12 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
                  SMRange(ErrorStart, ErrorEnd));
     }
+  case Match_RequiresPosSizeUImm6: {
+    SMLoc ErrorStart = Operands[3]->getStartLoc();
+    SMLoc ErrorEnd = Operands[4]->getEndLoc();
+    return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
+                 SMRange(ErrorStart, ErrorEnd));
+    }
   case Match_RequiresPosSizeRange33_64: {
     SMLoc ErrorStart = Operands[3]->getStartLoc();
     SMLoc ErrorEnd = Operands[4]->getEndLoc();
index 8bd2e791998f8bea94ff3c647e36c3b9702358db..ac92fdb6f9e46ca92c9c4aa9893e0dcd0d8629d7 100644 (file)
@@ -523,6 +523,10 @@ template <typename InsnType>
 static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
                                const void *Decoder);
 
+template <typename InsnType>
+static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
+                               const void *Decoder);
+
 static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
                                          uint64_t Address,
                                          const void *Decoder);
@@ -1055,6 +1059,60 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
   return MCDisassembler::Success;
 }
 
+// Override the generated disassembler to produce DEXT all the time. This is
+// for feature / behaviour parity with  binutils.
+template <typename InsnType>
+static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
+                               const void *Decoder) {
+  unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
+  unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
+  unsigned Size = 0;
+  unsigned Pos = 0;
+  bool IsMicroMips = false;
+
+  switch (MI.getOpcode()) {
+    case Mips::DEXT_MM64R6:
+      IsMicroMips = true;
+      LLVM_FALLTHROUGH;
+    case Mips::DEXT:
+      Pos = Lsb;
+      Size = Msbd + 1;
+      break;
+    case Mips::DEXTM_MM64R6:
+      IsMicroMips = true;
+      LLVM_FALLTHROUGH;
+    case Mips::DEXTM:
+      Pos = Lsb;
+      Size = Msbd + 1 + 32;
+      break;
+    case Mips::DEXTU_MM64R6:
+      IsMicroMips = true;
+      LLVM_FALLTHROUGH;
+    case Mips::DEXTU:
+      Pos = Lsb + 32;
+      Size = Msbd + 1;
+      break;
+    default:
+      llvm_unreachable("Unknown DEXT instruction!");
+  }
+
+  MI.setOpcode(IsMicroMips ? Mips::DEXT_MM64R6 : Mips::DEXT);
+
+  // Although the format of the instruction is similar, rs and rt are swapped
+  // for microMIPS64R6.
+  InsnType Rs = fieldFromInstruction(Insn, 21, 5);
+  InsnType Rt = fieldFromInstruction(Insn, 16, 5);
+  if (IsMicroMips)
+    std::swap(Rs, Rt);
+
+  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
+  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
+  MI.addOperand(MCOperand::createImm(Pos));
+  MI.addOperand(MCOperand::createImm(Size));
+
+  return MCDisassembler::Success;
+}
+
 // Override the generated disassembler to produce DINS all the time. This is
 // for feature / behaviour parity with binutils.
 template <typename InsnType>
index 4f7248e8d014e8553d8fb9612ecab832d38ab1cc..e0f4d83339262d0e4df620c99f5809da4f98f2bc 100644 (file)
@@ -111,11 +111,8 @@ class EXTBITS_DESC_BASE<string instr_asm, RegisterOperand RO, Operand PosOpnd,
   Format Form = FrmR;
   string BaseOpcode = instr_asm;
 }
-// TODO: Add 'pos + size' constraint check to dext* instructions
-//       DEXT: 0 < pos + size <= 63
-//       DEXTM, DEXTU: 32 < pos + size <= 64
 class DEXT_MMR6_DESC : EXTBITS_DESC_BASE<"dext", GPR64Opnd, uimm5_report_uimm6,
-                                         uimm5_plus1, MipsExt>;
+                                         uimm5_plus1_report_uimm6, MipsExt>;
 class DEXTM_MMR6_DESC : EXTBITS_DESC_BASE<"dextm", GPR64Opnd, uimm5,
                                           uimm5_plus33, MipsExt>;
 class DEXTU_MMR6_DESC : EXTBITS_DESC_BASE<"dextu", GPR64Opnd, uimm5_plus32,
@@ -367,12 +364,14 @@ let DecoderNamespace = "MicroMipsR6" in {
     def DAHI_MM64R6 : StdMMR6Rel, DAHI_MMR6_DESC, DAHI_MMR6_ENC, ISA_MICROMIPS64R6;
     def DATI_MM64R6 : StdMMR6Rel, DATI_MMR6_DESC, DATI_MMR6_ENC, ISA_MICROMIPS64R6;
   }
-  def DEXT_MM64R6 : StdMMR6Rel, DEXT_MMR6_DESC, DEXT_MMR6_ENC,
-                    ISA_MICROMIPS64R6;
-  def DEXTM_MM64R6 : StdMMR6Rel, DEXTM_MMR6_DESC, DEXTM_MMR6_ENC,
-                     ISA_MICROMIPS64R6;
-  def DEXTU_MM64R6 : StdMMR6Rel, DEXTU_MMR6_DESC, DEXTU_MMR6_ENC,
-                     ISA_MICROMIPS64R6;
+  let DecoderMethod = "DecodeDEXT" in {
+    def DEXT_MM64R6 : StdMMR6Rel, DEXT_MMR6_DESC, DEXT_MMR6_ENC,
+                      ISA_MICROMIPS64R6;
+    def DEXTM_MM64R6 : StdMMR6Rel, DEXTM_MMR6_DESC, DEXTM_MMR6_ENC,
+                       ISA_MICROMIPS64R6;
+    def DEXTU_MM64R6 : StdMMR6Rel, DEXTU_MMR6_DESC, DEXTU_MMR6_ENC,
+                       ISA_MICROMIPS64R6;
+  }
   def DALIGN_MM64R6 : StdMMR6Rel, DALIGN_MMR6_DESC, DALIGN_MMR6_ENC,
                       ISA_MICROMIPS64R6;
   def DDIV_MM64R6 : R6MMR6Rel, DDIV_MM64R6_DESC, DDIV_MM64R6_ENC,
@@ -572,3 +571,12 @@ def : MipsInstAlias<"dins $rt, $rs, $pos, $size",
                     (DINSU_MM64R6 GPR64Opnd:$rt, GPR64Opnd:$rs,
                                   uimm5_plus32:$pos, uimm5_plus1:$size), 0>,
                     ISA_MICROMIPS64R6;
+def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+                    (DEXTM_MM64R6 GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5:$pos,
+                                                 uimm5_plus33:$size), 0>,
+      ISA_MICROMIPS64R6;
+def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+                    (DEXTU_MM64R6 GPR64Opnd:$rt, GPR64Opnd:$rs,
+                                  uimm5_plus32:$pos, uimm5_plus1:$size), 0>,
+      ISA_MICROMIPS64R6;
+
index 3f0930355afc3d278f0ba59a1d47546b45c19d53..04a050c2ff4e6c3a58deb3b2e4fab69269878e26 100644 (file)
@@ -317,16 +317,22 @@ let isCodeGenOnly = 1 in
 def RDHWR64 : ReadHardware<GPR64Opnd, HWRegsOpnd>, RDHWR_FM;
 
 let AdditionalPredicates = [NotInMicroMips] in {
-  // The 'pos + size' constraints are enforced by the code that lowers into
-  // MipsISD::Ext.
-  def DEXT : ExtBase<"dext", GPR64Opnd, uimm5_report_uimm6, uimm5_plus1,
-                     immZExt5, immZExt5Plus1, MipsExt>, EXT_FM<3>,
-                     ISA_MIPS64R2;
-  def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5, uimm5_plus33, immZExt5,
-                      immZExt5Plus33, MipsExt>, EXT_FM<1>, ISA_MIPS64R2;
-  def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1,
-                      immZExt5Plus32, immZExt5Plus1, MipsExt>, EXT_FM<2>,
-                      ISA_MIPS64R2;
+  // The 'pos + size' constraints for code generation are enforced by the
+  // code that lowers into MipsISD::Ext.
+  // For assembly parsing, we alias dextu and dextm to dext, and match by
+  // operand were possible then check the 'pos + size' in MipsAsmParser.
+  // We override the generated decoder to enforce that dext always comes out
+  // for dextm and dextu like binutils.
+  let DecoderMethod = "DecodeDEXT" in {
+    def DEXT : ExtBase<"dext", GPR64Opnd, uimm5_report_uimm6,
+                       uimm5_plus1_report_uimm6, immZExt5, immZExt5Plus1,
+                       MipsExt>, EXT_FM<3>, ISA_MIPS64R2;
+    def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5, uimm5_plus33, immZExt5,
+                        immZExt5Plus33, MipsExt>, EXT_FM<1>, ISA_MIPS64R2;
+    def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1,
+                        immZExt5Plus32, immZExt5Plus1, MipsExt>, EXT_FM<2>,
+                        ISA_MIPS64R2;
+  }
   // The 'pos + size' constraints for code generation are enforced by the
   // code that lowers into MipsISD::Ins.
   // For assembly parsing, we alias dinsu and dinsm to dins, and match by
@@ -840,6 +846,12 @@ let AdditionalPredicates = [NotInMicroMips] in {
   def : MipsInstAlias<"dins $rt, $rs, $pos, $size",
                       (DINSU GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32:$pos,
                              uimm5_plus1:$size), 0>, ISA_MIPS64R2;
+  def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+                      (DEXTM GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5:$pos,
+                             uimm5_plus33:$size), 0>, ISA_MIPS64R2;
+  def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+                      (DEXTU GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32:$pos,
+                             uimm5_plus1:$size), 0>, ISA_MIPS64R2;
 
 // Two operand (implicit 0 selector) versions:
   def : MipsInstAlias<"dmtc0 $rt, $rd",
index 0ff1c4cf145e996e5d8e52c5fa9eff559abf0c13..50515808376fb123611df7266b3e6224835148e6 100644 (file)
@@ -690,9 +690,14 @@ def ConstantUImm5Plus32NormalizeAsmOperandClass
   // We must also subtract 32 when we render the operand.
   let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
 }
+def ConstantUImm5Plus1ReportUImm6AsmOperandClass
+    : ConstantUImmAsmOperandClass<
+          5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
+  let Name = "ConstantUImm5_Plus1_Report_UImm6";
+}
 def ConstantUImm5Plus1AsmOperandClass
     : ConstantUImmAsmOperandClass<
-          5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>;
+          5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
 def ConstantUImm5AsmOperandClass
     : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
 def ConstantSImm5AsmOperandClass
@@ -799,6 +804,13 @@ def uimm5_plus1 : Operand<i32> {
   let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
 }
 
+def uimm5_plus1_report_uimm6 : Operand<i32> {
+  let PrintMethod = "printUImm<6, 1>";
+  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
+  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
+  let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
+}
+
 def uimm5_plus32 : Operand<i32> {
   let PrintMethod = "printUImm<5, 32>";
   let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
index 66827e6d92061ce58f0ebf5eb5fd6fb28e9d0cb1..9186e66d4d0b52ab42d36dc34915cfa41d5cc4ed 100644 (file)
@@ -38,8 +38,8 @@
 0x42 0x23 0x00 0x04 # CHECK: dahi $3, $3, 4
 0x42 0x03 0x00 0x04 # CHECK: dati $3, $3, 4
 0x59 0x26 0x30 0xec # CHECK: dext $9, $6, 3, 7
-0x59 0x26 0x30 0xe4 # CHECK: dextm $9, $6, 3, 39
-0x59 0x26 0x30 0xd4 # CHECK: dextu $9, $6, 35, 7
+0x59 0x26 0x30 0xe4 # CHECK: dext $9, $6, 3, 39
+0x59 0x26 0x30 0xd4 # CHECK: dext $9, $6, 35, 7
 0x58 0x43 0x25 0x1c # CHECK: dalign $4, $2, $3, 5
 0x58 0xa4 0x19 0x18 # CHECK: ddiv $3, $4, $5
 0x58 0xa4 0x19 0x58 # CHECK: dmod $3, $4, $5
index ffe50e75bf453bd5184ba0ba531f734a98dcab29..2a864d3510243d1081bf62a44ec4b0b9171a782b 100644 (file)
   daui    $4, $4, -1       # CHECK: :[[@LINE]]:19: error: expected 16-bit unsigned immediate
   dati    $4, $4, -1       # CHECK: :[[@LINE]]:19: error: expected 16-bit unsigned immediate
   dati    $4, $5, 1        # CHECK: :[[@LINE]]:3: error: source and destination must match
-  # FIXME: Check various 'pos + size' constraints on dext*
   dext $2, $3, -1, 1   # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate
   dext $2, $3, 64, 1   # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate
   dext $2, $3, 1, 0    # CHECK: :[[@LINE]]:19: error: expected immediate in range 1 .. 32
-  dext $2, $3, 1, 33   # CHECK: :[[@LINE]]:19: error: expected immediate in range 1 .. 32
   dextm $2, $3, -1, 1  # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate
   dextm $2, $3, 32, 1  # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate
   dextm $2, $3, -1, 33 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate
index ec8281b1ebf0eeda35e3905ee7d286f12432c58d..f210cf44f0d365762ce0af3ff7595590725dc046 100644 (file)
@@ -10,8 +10,8 @@
 # RUN:     %s -o - | FileCheck --check-prefix=ASM %s
 
         dext $2, $4, 5, 10   # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 10
-        dextu $2, $4, 34, 6  # OBJ: dextu ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
-        dextm $2, $4, 5, 34  # OBJ: dextm ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
+        dextu $2, $4, 34, 6  # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
+        dextm $2, $4, 5, 34  # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
         dins $4, $5, 8, 10   # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 8, 10
         dinsm $4, $5, 30, 6  # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 30, 6
         dinsu $4, $5, 40, 13 # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 40, 13
         dins $2, $4, 5, 10   # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 5, 10
         dins $2, $4, 34, 6   # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
         dins $2, $4, 5, 34   # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
+        dext $2, $4, 5, 10   # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 10
+        dext $2, $4, 34, 6   # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
+        dext $2, $4, 5, 34   # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
         # check the edge values
-        dins $3, $4, 31, 1  # ASM: dins $3, $4, 31, 1
+        dins $3, $4, 31, 1   # ASM: dins $3, $4, 31, 1
         dins $3, $4, 31, 33  # ASM: dinsm $3, $4, 31, 33
         dins $3, $4, 32, 32  # ASM: dinsu $3, $4, 32, 32
+        dext $3, $4, 31, 32  # ASM: dext $3, $4, 31, 32
+        dext $3, $4, 31, 33  # ASM: dextm $3, $4, 31, 33
+        dext $3, $4, 32, 32  # ASM: dextu $3, $4, 32, 32
+
index 84438c6152814b96ede9e3c4461044212d7c5a61..9ebb5fc799bb750a007d7c6211c18e0e4cebf99b 100644 (file)
         andi $2, $3, 65536   # CHECK: :[[@LINE]]:22: error: expected 16-bit unsigned immediate
         cache -1, 255($7)    # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate
         cache 32, 255($7)    # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate
-        # FIXME: Check various 'pos + size' constraints on dext*
         dext $2, $3, -1, 1   # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
         dext $2, $3, 64, 1   # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
         dext $2, $3, 1, 0    # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 32
-        dext $2, $3, 1, 33   # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 32
         dextm $2, $3, -1, 1  # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
         dextm $2, $3, 32, 1  # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
         dextm $2, $3, -1, 33 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
         dextm $2, $3, 32, 33 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
         dextm $2, $3, 1, 32  # CHECK: :[[@LINE]]:26: error: expected immediate in range 33 .. 64
         dextm $2, $3, 1, 65  # CHECK: :[[@LINE]]:26: error: expected immediate in range 33 .. 64
+        dextm $3, $4, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
         dextu $2, $3, 31, 1  # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
         dextu $2, $3, 64, 1  # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
         dextu $2, $3, 32, 0  # CHECK: :[[@LINE]]:27: error: expected immediate in range 1 .. 32
         dextu $2, $3, 32, 33 # CHECK: :[[@LINE]]:27: error: expected immediate in range 1 .. 32
+        dextu $3, $4, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
         # FIXME: Check size on dins*
         dins $2, $3, -1, 1   # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
         dins $2, $3, 64, 1   # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
         dinsm $2, $3, -1, 1  # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
         dinsm $2, $3, 32, 1  # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
+        dinsm $4, $5, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
         dinsu $2, $3, 31, 1  # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
         dinsu $2, $3, 64, 1  # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
+        dinsu $4, $5, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
         drotr $2, $3, -1     # CHECK: :[[@LINE]]:23: error: expected 6-bit unsigned immediate
         drotr $2, $3, 64     # CHECK: :[[@LINE]]:23: error: expected 6-bit unsigned immediate
         drotr32 $2, $3, -1   # CHECK: :[[@LINE]]:25: error: expected 5-bit unsigned immediate
index 076e2fd7d2b5708416d6547f60b48c780f292e20..82f3a2b69f5526f4b7699e74afec659c1d73efcd 100644 (file)
@@ -23,6 +23,10 @@ local_label:
         break 7, 1024     # CHECK: :[[@LINE]]:18: error: expected 10-bit unsigned immediate
         break 1024, 1024  # CHECK: :[[@LINE]]:15: error: expected 10-bit unsigned immediate
         dati $2, $3, 1    # CHECK: :[[@LINE]]:9: error: source and destination must match
+        dextm $3, $4, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
+        dextu $3, $4, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
+        dinsm $4, $5, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
+        dinsu $4, $5, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
         lh  $33, 8($4)    # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
         lhe $34, 8($2)    # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
         lhu $35, 8($2)    # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction