[llvm] r366555 - [ARM] Add <saturate> operand to SQRSHRL and UQRSHLL

Mikhail Maltsev via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 19 02:46:28 PDT 2019


Author: miyuki
Date: Fri Jul 19 02:46:28 2019
New Revision: 366555

URL: http://llvm.org/viewvc/llvm-project?rev=366555&view=rev
Log:
[ARM] Add <saturate> operand to SQRSHRL and UQRSHLL

Summary:
According to the new Armv8-M specification
https://static.docs.arm.com/ddi0553/bh/DDI0553B_h_armv8m_arm.pdf the
instructions SQRSHRL and UQRSHLL now have an additional immediate
operand <saturate>. The new assembly syntax is:

SQRSHRL<c> RdaLo, RdaHi, #<saturate>, Rm
UQRSHLL<c> RdaLo, RdaHi, #<saturate>, Rm

where <saturate> can be either 64 (the existing behavior) or 48, in
that case the result is saturated to 48 bits.

The new operand is encoded as follows:
  #64 Encoded as sat = 0
  #48 Encoded as sat = 1
sat is bit 7 of the instruction bit pattern.

This patch adds a new assembler operand class MveSaturateOperand which
implements parsing and encoding. Decoding is implemented in
DecodeMVEOverlappingLongShift.

Reviewers: ostannard, simon_tatham, t.p.northover, samparker, dmgreen, SjoerdMeijer

Reviewed By: simon_tatham

Subscribers: javed.absar, kristof.beyls, hiraditya, pbarrio, llvm-commits

Tags: #llvm

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

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
    llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
    llvm/trunk/test/MC/ARM/mve-scalar-shift.s
    llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt

Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Fri Jul 19 02:46:28 2019
@@ -2724,6 +2724,16 @@ def complexrotateopodd : Operand<i32> {
   let PrintMethod = "printComplexRotationOp<180, 90>";
 }
 
+def MveSaturateOperand : AsmOperandClass {
+  let PredicateMethod = "isMveSaturateOp";
+  let DiagnosticString = "saturate operand must be 48 or 64";
+  let Name = "MveSaturate";
+}
+def saturateop : Operand<i32> {
+  let ParserMatchClass = MveSaturateOperand;
+  let PrintMethod = "printMveSaturateOp";
+}
+
 // Data type suffix token aliases. Implements Table A7-3 in the ARM ARM.
 def : TokenAlias<".s8", ".i8">;
 def : TokenAlias<".u8", ".i8">;

Modified: llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrMVE.td?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrMVE.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrMVE.td Fri Jul 19 02:46:28 2019
@@ -403,18 +403,17 @@ class MVE_ScalarShiftDRegImm<string inam
   let Inst{3-0} = 0b1111;
 }
 
-class MVE_ScalarShiftDRegReg<string iname, bit op5, bit op16,
-                             list<dag> pattern=[]>
+class MVE_ScalarShiftDRegRegBase<string iname, dag iops, string asm,
+                                 bit op5, bit op16, list<dag> pattern=[]>
   : MVE_ScalarShiftDoubleReg<
-     iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm),
-     "$RdaLo, $RdaHi, $Rm", "@earlyclobber $RdaHi, at earlyclobber $RdaLo,"
-                            "$RdaLo = $RdaLo_src,$RdaHi = $RdaHi_src",
+     iname, iops, asm, "@earlyclobber $RdaHi, at earlyclobber $RdaLo,"
+                       "$RdaLo = $RdaLo_src,$RdaHi = $RdaHi_src",
      pattern> {
   bits<4> Rm;
 
   let Inst{16} = op16;
   let Inst{15-12} = Rm{3-0};
-  let Inst{7-6} = 0b00;
+  let Inst{6} = 0b0;
   let Inst{5} = op5;
   let Inst{4} = 0b0;
   let Inst{3-0} = 0b1101;
@@ -427,13 +426,30 @@ class MVE_ScalarShiftDRegReg<string inam
   let DecoderMethod = "DecodeMVEOverlappingLongShift";
 }
 
-def MVE_ASRLr   : MVE_ScalarShiftDRegReg<"asrl",    0b1,  0b0, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
+class MVE_ScalarShiftDRegReg<string iname, bit op5, list<dag> pattern=[]>
+  : MVE_ScalarShiftDRegRegBase<
+     iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm),
+     "$RdaLo, $RdaHi, $Rm", op5, 0b0, pattern> {
+
+  let Inst{7} = 0b0;
+}
+
+class MVE_ScalarShiftDRegRegWithSat<string iname, bit op5, list<dag> pattern=[]>
+  : MVE_ScalarShiftDRegRegBase<
+     iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm, saturateop:$sat),
+     "$RdaLo, $RdaHi, $sat, $Rm", op5, 0b1, pattern> {
+  bit sat;
+
+  let Inst{7} = sat;
+}
+
+def MVE_ASRLr   : MVE_ScalarShiftDRegReg<"asrl",    0b1,  [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
                                         (ARMasrl tGPREven:$RdaLo_src,
                                         tGPROdd:$RdaHi_src, rGPR:$Rm))]>;
 def MVE_ASRLi   : MVE_ScalarShiftDRegImm<"asrl",    0b10, ?, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
                                         (ARMasrl tGPREven:$RdaLo_src,
                                         tGPROdd:$RdaHi_src, (i32 imm:$imm)))]>;
-def MVE_LSLLr   : MVE_ScalarShiftDRegReg<"lsll",    0b0,  0b0, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
+def MVE_LSLLr   : MVE_ScalarShiftDRegReg<"lsll",    0b0,  [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
                                         (ARMlsll tGPREven:$RdaLo_src,
                                         tGPROdd:$RdaHi_src, rGPR:$Rm))]>;
 def MVE_LSLLi   : MVE_ScalarShiftDRegImm<"lsll",    0b00, ?, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
@@ -443,11 +459,11 @@ def MVE_LSRL    : MVE_ScalarShiftDRegImm
                                         (ARMlsrl tGPREven:$RdaLo_src,
                                         tGPROdd:$RdaHi_src, (i32 imm:$imm)))]>;
 
-def MVE_SQRSHRL : MVE_ScalarShiftDRegReg<"sqrshrl", 0b1,  0b1>;
+def MVE_SQRSHRL : MVE_ScalarShiftDRegRegWithSat<"sqrshrl", 0b1>;
 def MVE_SQSHLL  : MVE_ScalarShiftDRegImm<"sqshll",  0b11, 0b1>;
 def MVE_SRSHRL  : MVE_ScalarShiftDRegImm<"srshrl",  0b10, 0b1>;
 
-def MVE_UQRSHLL : MVE_ScalarShiftDRegReg<"uqrshll", 0b0,  0b1>;
+def MVE_UQRSHLL : MVE_ScalarShiftDRegRegWithSat<"uqrshll", 0b0>;
 def MVE_UQSHLL  : MVE_ScalarShiftDRegImm<"uqshll",  0b00, 0b1>;
 def MVE_URSHRL  : MVE_ScalarShiftDRegImm<"urshrl",  0b01, 0b1>;
 

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Fri Jul 19 02:46:28 2019
@@ -2275,6 +2275,14 @@ public:
     return Value >= 1 && Value <= 32;
   }
 
+  bool isMveSaturateOp() const {
+    if (!isImm()) return false;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    if (!CE) return false;
+    uint64_t Value = CE->getValue();
+    return Value == 48 || Value == 64;
+  }
+
   bool isITCondCodeNoAL() const {
     if (!isITCondCode()) return false;
     ARMCC::CondCodes CC = getCondCode();
@@ -3370,6 +3378,14 @@ public:
     Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
   }
 
+  void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    unsigned Imm = CE->getValue();
+    assert((Imm == 48 || Imm == 64) && "Invalid saturate operand");
+    Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
+  }
+
   void print(raw_ostream &OS) const override;
 
   static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S) {

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Fri Jul 19 02:46:28 2019
@@ -6503,6 +6503,13 @@ static DecodeStatus DecodeMVEOverlapping
   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  if (Inst.getOpcode() == ARM::MVE_SQRSHRL ||
+      Inst.getOpcode() == ARM::MVE_UQRSHLL) {
+    unsigned Saturate = fieldFromInstruction(Insn, 7, 1);
+    // Saturate, the bit position for saturation
+    Inst.addOperand(MCOperand::createImm(Saturate));
+  }
+
   return S;
 }
 

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp Fri Jul 19 02:46:28 2019
@@ -1676,3 +1676,11 @@ void ARMInstPrinter::printExpandedImmOpe
   O.write_hex(Val);
   O << markup(">");
 }
+
+void ARMInstPrinter::printMveSaturateOp(const MCInst *MI, unsigned OpNum,
+                                        const MCSubtargetInfo &STI,
+                                        raw_ostream &O) {
+  uint32_t Val = MI->getOperand(OpNum).getImm();
+  assert(Val <= 1 && "Invalid MVE saturate operand");
+  O << "#" << (Val == 1 ? 48 : 64);
+}

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h Fri Jul 19 02:46:28 2019
@@ -262,7 +262,8 @@ public:
                                 const MCSubtargetInfo &STI, raw_ostream &O);
   void printExpandedImmOperand(const MCInst *MI, unsigned OpNum,
                                const MCSubtargetInfo &STI, raw_ostream &O);
-
+  void printMveSaturateOp(const MCInst *MI, unsigned OpNum,
+                         const MCSubtargetInfo &STI, raw_ostream &O);
 private:
   unsigned DefaultAltIdx = ARM::NoRegAltName;
 };

Modified: llvm/trunk/test/MC/ARM/mve-scalar-shift.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/mve-scalar-shift.s?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/mve-scalar-shift.s (original)
+++ llvm/trunk/test/MC/ARM/mve-scalar-shift.s Fri Jul 19 02:46:28 2019
@@ -111,9 +111,13 @@ sqrshr  lr, r12
 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
 sqrshr  r11, r12
 
-# CHECK: sqrshrl lr, r3, r8  @ encoding: [0x5f,0xea,0x2d,0x83]
+# CHECK: sqrshrl lr, r3, #64, r8  @ encoding: [0x5f,0xea,0x2d,0x83]
 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
-sqrshrl lr, r3, r8
+sqrshrl lr, r3, #64, r8
+
+# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: saturate operand must be 48 or 64
+# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+sqrshrl lr, r3, #32, r8
 
 # CHECK: sqshl   lr, #17  @ encoding: [0x5e,0xea,0x7f,0x4f]
 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
@@ -135,9 +139,13 @@ srshrl  lr, r11, #23
 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
 uqrshl  lr, r1
 
-# CHECK: uqrshll lr, r1, r4  @ encoding: [0x5f,0xea,0x0d,0x41]
+# CHECK: uqrshll lr, r1, #48, r4  @ encoding: [0x5f,0xea,0x8d,0x41]
 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
-uqrshll lr, r1, r4
+uqrshll lr, r1, #48, r4
+
+# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: saturate operand must be 48 or 64
+# ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
+uqrshll lr, r1, #0, r4
 
 # CHECK: uqshl   r0, #1  @ encoding: [0x50,0xea,0x4f,0x0f]
 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve

Modified: llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt?rev=366555&r1=366554&r2=366555&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt Fri Jul 19 02:46:28 2019
@@ -27,7 +27,11 @@
 # CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding
 
 [0x5f 0xea 0x2d 0x83]
-# CHECK: sqrshrl lr, r3, r8  @ encoding: [0x5f,0xea,0x2d,0x83]
+# CHECK: sqrshrl lr, r3, #64, r8  @ encoding: [0x5f,0xea,0x2d,0x83]
+# CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x5f 0xea 0xad 0x83]
+# CHECK: sqrshrl lr, r3, #48, r8  @ encoding: [0x5f,0xea,0xad,0x83]
 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x5e 0xea 0x7f 0x4f]
@@ -63,7 +67,11 @@
 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x5f 0xea 0x0d 0x41]
-# CHECK: uqrshll lr, r1, r4  @ encoding: [0x5f,0xea,0x0d,0x41]
+# CHECK: uqrshll lr, r1, #64, r4  @ encoding: [0x5f,0xea,0x0d,0x41]
+# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding
+
+[0x5f 0xea 0x8d 0x41]
+# CHECK: uqrshll lr, r1, #48, r4  @ encoding: [0x5f,0xea,0x8d,0x41]
 # CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding
 
 [0x50 0xea 0x4f 0x0f]




More information about the llvm-commits mailing list