[NFC][RISCV] Move vmsge{u}.vx processing to RISCVAsmParser.
authorHsiangkai Wang <kai.wang@sifive.com>
Fri, 1 Jan 2021 16:29:40 +0000 (00:29 +0800)
committerHsiangkai Wang <kai.wang@sifive.com>
Sat, 2 Jan 2021 00:42:53 +0000 (08:42 +0800)
We could expand vmsge{u}.vx pseudo instructions in RISCVAsmParser.
It is more appropriate to expand it before encoding.

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

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
llvm/test/MC/RISCV/rvv/compare.s

index c735aaf..4172d33 100644 (file)
@@ -129,6 +129,9 @@ class RISCVAsmParser : public MCTargetAsmParser {
   void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width,
                         SMLoc IDLoc, MCStreamer &Out);
 
+  // Helper to emit pseudo vmsge{u}.vx instruction.
+  void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
+
   // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
   // Enforcing this using a restricted register class for the second input
   // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
@@ -2257,6 +2260,59 @@ void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend,
                           .addImm(ShAmt));
 }
 
+void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
+                               MCStreamer &Out) {
+  if (Inst.getNumOperands() == 3) {
+    // unmasked va >= x
+    //
+    //  pseudoinstruction: vmsge{u}.vx vd, va, x
+    //  expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
+    emitToStreamer(Out, MCInstBuilder(Opcode)
+                            .addOperand(Inst.getOperand(0))
+                            .addOperand(Inst.getOperand(1))
+                            .addOperand(Inst.getOperand(2))
+                            .addReg(RISCV::NoRegister));
+    emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
+                            .addOperand(Inst.getOperand(0))
+                            .addOperand(Inst.getOperand(0))
+                            .addOperand(Inst.getOperand(0)));
+  } else if (Inst.getNumOperands() == 4) {
+    // masked va >= x, vd != v0
+    //
+    //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t
+    //  expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
+    assert(Inst.getOperand(0).getReg() != RISCV::V0 &&
+           "The destination register should not be V0.");
+    emitToStreamer(Out, MCInstBuilder(Opcode)
+                            .addOperand(Inst.getOperand(0))
+                            .addOperand(Inst.getOperand(1))
+                            .addOperand(Inst.getOperand(2))
+                            .addOperand(Inst.getOperand(3)));
+    emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
+                            .addOperand(Inst.getOperand(0))
+                            .addOperand(Inst.getOperand(0))
+                            .addReg(RISCV::V0));
+  } else if (Inst.getNumOperands() == 5) {
+    // masked va >= x, vd == v0
+    //
+    //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
+    //  expansion: vmslt{u}.vx vt, va, x;  vmandnot.mm vd, vd, vt
+    assert(Inst.getOperand(0).getReg() == RISCV::V0 &&
+           "The destination register should be V0.");
+    assert(Inst.getOperand(1).getReg() != RISCV::V0 &&
+           "The temporary vector register should not be V0.");
+    emitToStreamer(Out, MCInstBuilder(Opcode)
+                            .addOperand(Inst.getOperand(1))
+                            .addOperand(Inst.getOperand(2))
+                            .addOperand(Inst.getOperand(3))
+                            .addOperand(Inst.getOperand(4)));
+    emitToStreamer(Out, MCInstBuilder(RISCV::VMANDNOT_MM)
+                            .addOperand(Inst.getOperand(0))
+                            .addOperand(Inst.getOperand(0))
+                            .addOperand(Inst.getOperand(1)));
+  }
+}
+
 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
                                          OperandVector &Operands) {
   assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");
@@ -2432,6 +2488,16 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
   case RISCV::PseudoZEXT_W:
     emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out);
     return false;
+  case RISCV::PseudoVMSGEU_VX:
+  case RISCV::PseudoVMSGEU_VX_M:
+  case RISCV::PseudoVMSGEU_VX_M_T:
+    emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
+    return false;
+  case RISCV::PseudoVMSGE_VX:
+  case RISCV::PseudoVMSGE_VX_M:
+  case RISCV::PseudoVMSGE_VX_M_T:
+    emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
+    return false;
   }
 
   emitToStreamer(Out, Inst);
index ddbf85e..1b7425a 100644 (file)
@@ -60,10 +60,6 @@ public:
                       SmallVectorImpl<MCFixup> &Fixups,
                       const MCSubtargetInfo &STI) const;
 
-  void expandVMSGE(const MCInst &MI, raw_ostream &OS,
-                   SmallVectorImpl<MCFixup> &Fixups,
-                   const MCSubtargetInfo &STI) const;
-
   /// TableGen'erated function for getting the binary encoding for an
   /// instruction.
   uint64_t getBinaryCodeForInstr(const MCInst &MI,
@@ -191,92 +187,6 @@ void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS,
   support::endian::write(OS, Binary, support::little);
 }
 
-void RISCVMCCodeEmitter::expandVMSGE(const MCInst &MI, raw_ostream &OS,
-                                     SmallVectorImpl<MCFixup> &Fixups,
-                                     const MCSubtargetInfo &STI) const {
-  MCInst TmpInst;
-  uint32_t Binary;
-  unsigned Opcode;
-  switch (MI.getOpcode()) {
-  default:
-    llvm_unreachable("Unexpacted opcode. It should be vmsgeu.vx or vmsge.vx.");
-  case RISCV::PseudoVMSGEU_VX:
-  case RISCV::PseudoVMSGEU_VX_M:
-  case RISCV::PseudoVMSGEU_VX_M_T:
-    Opcode = RISCV::VMSLTU_VX;
-    break;
-  case RISCV::PseudoVMSGE_VX:
-  case RISCV::PseudoVMSGE_VX_M:
-  case RISCV::PseudoVMSGE_VX_M_T:
-    Opcode = RISCV::VMSLT_VX;
-    break;
-  }
-  if (MI.getNumOperands() == 3) {
-    // unmasked va >= x
-    //
-    //  pseudoinstruction: vmsge{u}.vx vd, va, x
-    //  expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
-    TmpInst = MCInstBuilder(Opcode)
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(1))
-                  .addOperand(MI.getOperand(2))
-                  .addReg(RISCV::NoRegister);
-    Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
-    support::endian::write(OS, Binary, support::little);
-
-    TmpInst = MCInstBuilder(RISCV::VMNAND_MM)
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(0));
-    Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
-    support::endian::write(OS, Binary, support::little);
-  } else if (MI.getNumOperands() == 4) {
-    // masked va >= x, vd != v0
-    //
-    //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t
-    //  expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
-    assert(MI.getOperand(0).getReg() != RISCV::V0 &&
-           "The destination register should not be V0.");
-    TmpInst = MCInstBuilder(Opcode)
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(1))
-                  .addOperand(MI.getOperand(2))
-                  .addOperand(MI.getOperand(3));
-    Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
-    support::endian::write(OS, Binary, support::little);
-
-    TmpInst = MCInstBuilder(RISCV::VMXOR_MM)
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(0))
-                  .addReg(RISCV::V0);
-    Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
-    support::endian::write(OS, Binary, support::little);
-  } else if (MI.getNumOperands() == 5) {
-    // masked va >= x, vd == v0
-    //
-    //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
-    //  expansion: vmslt{u}.vx vt, va, x;  vmandnot.mm vd, vd, vt
-    assert(MI.getOperand(0).getReg() == RISCV::V0 &&
-           "The destination register should be V0.");
-    assert(MI.getOperand(1).getReg() != RISCV::V0 &&
-           "The temporary vector register should not be V0.");
-    TmpInst = MCInstBuilder(Opcode)
-                  .addOperand(MI.getOperand(1))
-                  .addOperand(MI.getOperand(2))
-                  .addOperand(MI.getOperand(3))
-                  .addOperand(MI.getOperand(4));
-    Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
-    support::endian::write(OS, Binary, support::little);
-
-    TmpInst = MCInstBuilder(RISCV::VMANDNOT_MM)
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(1));
-    Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
-    support::endian::write(OS, Binary, support::little);
-  }
-}
-
 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
                                            SmallVectorImpl<MCFixup> &Fixups,
                                            const MCSubtargetInfo &STI) const {
@@ -305,16 +215,6 @@ void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
     return;
   }
 
-  if (MI.getOpcode() == RISCV::PseudoVMSGEU_VX ||
-      MI.getOpcode() == RISCV::PseudoVMSGE_VX ||
-      MI.getOpcode() == RISCV::PseudoVMSGEU_VX_M ||
-      MI.getOpcode() == RISCV::PseudoVMSGE_VX_M ||
-      MI.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T ||
-      MI.getOpcode() == RISCV::PseudoVMSGE_VX_M_T) {
-    expandVMSGE(MI, OS, Fixups, STI);
-    return;
-  }
-
   switch (Size) {
   default:
     llvm_unreachable("Unhandled encodeInstruction length!");
index 6b5eb21..264a324 100644 (file)
@@ -353,7 +353,8 @@ vmsge.vi v8, v4, 16
 vmsgeu.vx v8, v4, a0
 # CHECK-INST: vmsltu.vx v8, v4, a0
 # CHECK-INST: vmnot.m v8, v8
-# CHECK-ENCODING: [0x57,0x44,0x45,0x6a,0x57,0x24,0x84,0x76]
+# CHECK-ENCODING: [0x57,0x44,0x45,0x6a]
+# CHECK-ENCODING: [0x57,0x24,0x84,0x76]
 # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions)
 # CHECK-UNKNOWN: 57 44 45 6a <unknown>
 # CHECK-UNKNOWN: 57 24 84 76 <unknown>
@@ -361,7 +362,8 @@ vmsgeu.vx v8, v4, a0
 vmsge.vx v0, v4, a0
 # CHECK-INST: vmslt.vx v0, v4, a0
 # CHECK-INST: vmnot.m v0, v0
-# CHECK-ENCODING: [0x57,0x40,0x45,0x6e,0x57,0x20,0x00,0x76]
+# CHECK-ENCODING: [0x57,0x40,0x45,0x6e]
+# CHECK-ENCODING: [0x57,0x20,0x00,0x76]
 # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions)
 # CHECK-UNKNOWN: 57 40 45 6e <unknown>
 # CHECK-UNKNOWN: 57 20 00 76 <unknown>
@@ -369,7 +371,8 @@ vmsge.vx v0, v4, a0
 vmsge.vx v8, v4, a0
 # CHECK-INST: vmslt.vx v8, v4, a0
 # CHECK-INST: vmnot.m v8, v8
-# CHECK-ENCODING: [0x57,0x44,0x45,0x6e,0x57,0x24,0x84,0x76]
+# CHECK-ENCODING: [0x57,0x44,0x45,0x6e]
+# CHECK-ENCODING: [0x57,0x24,0x84,0x76]
 # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions)
 # CHECK-UNKNOWN: 57 44 45 6e <unknown>
 # CHECK-UNKNOWN: 57 24 84 76 <unknown>
@@ -377,7 +380,8 @@ vmsge.vx v8, v4, a0
 vmsgeu.vx v8, v4, a0, v0.t
 # CHECK-INST: vmsltu.vx v8, v4, a0, v0.t
 # CHECK-INST: vmxor.mm v8, v8, v0
-# CHECK-ENCODING: [0x57,0x44,0x45,0x68,0x57,0x24,0x80,0x6e]
+# CHECK-ENCODING: [0x57,0x44,0x45,0x68]
+# CHECK-ENCODING: [0x57,0x24,0x80,0x6e]
 # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions)
 # CHECK-UNKNOWN: 57 44 45 68 <unknown>
 # CHECK-UNKNOWN: 57 24 80 6e <unknown>
@@ -385,7 +389,8 @@ vmsgeu.vx v8, v4, a0, v0.t
 vmsge.vx v8, v4, a0, v0.t
 # CHECK-INST: vmslt.vx v8, v4, a0, v0.t
 # CHECK-INST: vmxor.mm v8, v8, v0
-# CHECK-ENCODING: [0x57,0x44,0x45,0x6c,0x57,0x24,0x80,0x6e]
+# CHECK-ENCODING: [0x57,0x44,0x45,0x6c]
+# CHECK-ENCODING: [0x57,0x24,0x80,0x6e]
 # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions)
 # CHECK-UNKNOWN: 57 44 45 6c <unknown>
 # CHECK-UNKNOWN: 57 24 80 6e <unknown>
@@ -393,7 +398,8 @@ vmsge.vx v8, v4, a0, v0.t
 vmsgeu.vx v0, v4, a0, v0.t, v2
 # CHECK-INST: vmsltu.vx v2, v4, a0, v0.t
 # CHECK-INST: vmandnot.mm v0, v0, v2
-# CHECK-ENCODING: [0x57,0x41,0x45,0x68,0x57,0x20,0x01,0x62]
+# CHECK-ENCODING: [0x57,0x41,0x45,0x68]
+# CHECK-ENCODING: [0x57,0x20,0x01,0x62]
 # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions)
 # CHECK-UNKNOWN: 57 41 45 68 <unknown>
 # CHECK-UNKNOWN: 57 20 01 62 <unknown>
@@ -401,7 +407,8 @@ vmsgeu.vx v0, v4, a0, v0.t, v2
 vmsge.vx v0, v4, a0, v0.t, v2
 # CHECK-INST: vmslt.vx v2, v4, a0, v0.t
 # CHECK-INST: vmandnot.mm v0, v0, v2
-# CHECK-ENCODING: [0x57,0x41,0x45,0x6c,0x57,0x20,0x01,0x62]
+# CHECK-ENCODING: [0x57,0x41,0x45,0x6c]
+# CHECK-ENCODING: [0x57,0x20,0x01,0x62]
 # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions)
 # CHECK-UNKNOWN: 57 41 45 6c <unknown>
 # CHECK-UNKNOWN: 57 20 01 62 <unknown>