ARM assembly parsing and encoding for SSAT16 instruction.
authorJim Grosbach <grosbach@apple.com>
Mon, 25 Jul 2011 23:09:14 +0000 (23:09 +0000)
committerJim Grosbach <grosbach@apple.com>
Mon, 25 Jul 2011 23:09:14 +0000 (23:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136006 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.h
test/MC/ARM/basic-arm-instructions.s
test/MC/ARM/diagnostics.s
utils/TableGen/EDEmitter.cpp

index 6e9743ffad531e5209f225b305b277f232534047..83a25148040b0d87120cfb03d17d80e0adef7e06 100644 (file)
@@ -543,10 +543,20 @@ def imm1_32_XFORM: SDNodeXForm<imm, [{
 def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }
 def imm1_32 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 32; }],
     imm1_32_XFORM> {
-  let PrintMethod = "printImm1_32Operand";
+  let PrintMethod = "printImmPlusOneOperand";
   let ParserMatchClass = Imm1_32AsmOperand;
 }
 
+def imm1_16_XFORM: SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32);
+}]>;
+def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; }
+def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }],
+    imm1_16_XFORM> {
+  let PrintMethod = "printImmPlusOneOperand";
+  let ParserMatchClass = Imm1_16AsmOperand;
+}
+
 // Define ARM specific addressing modes.
 // addrmode_imm12 := reg +/- imm12
 //
@@ -2709,7 +2719,7 @@ def SSAT : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$Rn, shift_imm:$sh),
   let Inst{3-0} = Rn;
 }
 
-def SSAT16 : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$Rn), SatFrm,
+def SSAT16 : AI<(outs GPR:$Rd), (ins imm1_16:$sat_imm, GPR:$Rn), SatFrm,
                 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {
   bits<4> Rd;
   bits<4> sat_imm;
index 808ae51a60027edab8b68b033b3924f1cc94e39d..1a9ab1c8763a0a53c3033082202fbb87fb66d405 100644 (file)
@@ -1935,7 +1935,7 @@ def t2SSAT: T2SatI<
 }
 
 def t2SSAT16: T2SatI<
-                (outs rGPR:$Rd), (ins imm1_32:$sat_imm, rGPR:$Rn), NoItinerary,
+                (outs rGPR:$Rd), (ins imm1_16:$sat_imm, rGPR:$Rn), NoItinerary,
                 "ssat16", "\t$Rd, $sat_imm, $Rn",
                 [/* For disassembly only; pattern left blank */]>,
           Requires<[IsThumb2, HasThumb2DSP]> {
index 02ed5477d4f989af787893323402d6a897ed3b4b..f6f8adc666cc4a4c8046ee59a8e05c7d5865e363 100644 (file)
@@ -433,6 +433,14 @@ public:
     int64_t Value = CE->getValue();
     return Value >= 0 && Value < 32;
   }
+  bool isImm1_16() const {
+    if (Kind != Immediate)
+      return false;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+    return Value > 0 && Value < 17;
+  }
   bool isImm1_32() const {
     if (Kind != Immediate)
       return false;
@@ -704,6 +712,14 @@ public:
     addExpr(Inst, getImm());
   }
 
+  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    // The constant encodes as the immediate-1, and we store in the instruction
+    // the bits as encoded, so subtract off one here.
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
+  }
+
   void addImm1_32Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     // The constant encodes as the immediate-1, and we store in the instruction
index 296080a8174ad9df5dd604c120c4280bfca1591c..3e58631c6ceebb53f1129a5d2ac58c1bb6baf894 100644 (file)
@@ -830,8 +830,8 @@ void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
   O << "#0x" << utohexstr(Val);
 }
 
-void ARMInstPrinter::printImm1_32Operand(const MCInst *MI, unsigned OpNum,
-                                         raw_ostream &O) {
+void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
+                                            raw_ostream &O) {
   unsigned Imm = MI->getOperand(OpNum).getImm();
   O << "#" << Imm + 1;
 }
index 208a3a71f143fd39aa787d13416ce1f7e2b16db8..c254ace6bc61a45fbd33bfd709adcfe19008e5ab 100644 (file)
@@ -114,7 +114,7 @@ public:
   void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
-  void printImm1_32Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
   void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 };
index 0439e70c441ce1b33a4830e7d7f32946711c2926..b00b70b7b4d10d7ce6b68bee4e267dcf77ea2097 100644 (file)
@@ -1631,6 +1631,17 @@ _func:
 @ CHECK: ssat  r8, #1, r10, asr #32    @ encoding: [0x5a,0x80,0xa0,0xe6]
 @ CHECK: ssat  r8, #1, r10, asr #1     @ encoding: [0xda,0x80,0xa0,0xe6]
 
+
+@------------------------------------------------------------------------------
+@ SSAT16
+@------------------------------------------------------------------------------
+       ssat16  r2, #1, r7
+       ssat16  r3, #16, r5
+
+@ CHECK: ssat16        r2, #1, r7              @ encoding: [0x37,0x2f,0xa0,0xe6]
+@ CHECK: ssat16        r3, #16, r5             @ encoding: [0x35,0x3f,0xaf,0xe6]
+
+
 @------------------------------------------------------------------------------
 @ STM*
 @------------------------------------------------------------------------------
index a8b2d9d4faa08797f2928a8662a2383d3172d3cb..aff242cc0beefb862303b85acff4fea3212a3ede 100644 (file)
 @ CHECK: error: shift amount must be an immediate
 @ CHECK:         ssat    r8, #1, r10, lsl #fred
 @ CHECK:                                   ^
+
+        @ Out of range immediates for SSAT16
+       ssat16  r2, #0, r7
+       ssat16  r3, #17, r5
+
+@ CHECK: error: invalid operand for instruction
+@ CHECK:       ssat16  r2, #0, r7
+@ CHECK:                   ^
+@ CHECK: error: invalid operand for instruction
+@ CHECK:       ssat16  r3, #17, r5
+@ CHECK:                   ^
index 3001192e7f89afb47232bb33fb33e3f942a63e34..c9542cb8e75c6280a25271ad956f239393932f45 100644 (file)
@@ -587,6 +587,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   IMM("neg_zero");
   IMM("imm0_31");
   IMM("imm0_31_m1");
+  IMM("imm1_16");
   IMM("imm1_32");
   IMM("nModImm");
   IMM("imm0_7");