[llvm] 6b3eba7 - [ARC] Add disassembly for the conditioned move immediate instruction

Mark Schimmel via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 12 12:37:07 PDT 2021


Author: Thomas Johnson
Date: 2021-07-12T12:35:56-07:00
New Revision: 6b3eba7c285c9399f1a198d5490ac9522f2fd614

URL: https://github.com/llvm/llvm-project/commit/6b3eba7c285c9399f1a198d5490ac9522f2fd614
DIFF: https://github.com/llvm/llvm-project/commit/6b3eba7c285c9399f1a198d5490ac9522f2fd614.diff

LOG: [ARC] Add disassembly for the conditioned move immediate instruction

This change is a step towards implementing codegen for __builtin_clz().
Full support for CLZ with a regression test will follow shortly.
Differential Revision: https://reviews.llvm.org/D105560

Added: 
    

Modified: 
    llvm/lib/Target/ARC/ARCInstrFormats.td
    llvm/lib/Target/ARC/ARCInstrInfo.td
    llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
    llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp
    llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARC/ARCInstrFormats.td b/llvm/lib/Target/ARC/ARCInstrFormats.td
index 584844d495530..c95c71ff007bb 100644
--- a/llvm/lib/Target/ARC/ARCInstrFormats.td
+++ b/llvm/lib/Target/ARC/ARCInstrFormats.td
@@ -261,6 +261,31 @@ class F32_SOP_RR<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
   let Inst{5-0} = subop;
 }
 
+// Single Operand Immediate Instructions.
+// 1-register, unsigned 6-bit immediate Single Operand instruction.
+// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
+// |B[2-0]  | 1| 1|            subop| F|B[5-3]  |U6           |1|cc       |
+class F32_SOP_CC_RU6<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
+                     string asmstr, list<dag> pattern> :
+  InstARC<4, outs, ins, asmstr, pattern> {
+
+  bits<5> cc;
+  bits<6> U6;
+  bits<6> B;
+
+  let Inst{31-27} = major;
+  let Inst{26-24} = B{2-0};
+  let Inst{23-22} = 0b11;
+  let Inst{21-16} = subop;
+  let Inst{15} = F;
+  let Inst{14-12} = B{5-3};
+  let Inst{11-6} = U6;
+  let Inst{5} = 1;
+  let Inst{4-0} = cc;
+
+  let DecoderMethod = "DecodeCCRU6Instruction";
+}
+
 // Dual Operand Instructions.  Inst[21-16] specifies the specific operation
 // for this format.
 

diff  --git a/llvm/lib/Target/ARC/ARCInstrInfo.td b/llvm/lib/Target/ARC/ARCInstrInfo.td
index 1dc81dd76a523..23e2d57b625ec 100644
--- a/llvm/lib/Target/ARC/ARCInstrInfo.td
+++ b/llvm/lib/Target/ARC/ARCInstrInfo.td
@@ -12,6 +12,24 @@
 
 include "ARCInstrFormats.td"
 
+//===----------------------------------------------------------------------===//
+// Operand Pattern Stuff.
+//===----------------------------------------------------------------------===//
+
+// Operand for printing out a condition code.
+let PrintMethod = "printCCOperand" in
+  def CCOp : PredicateOperand<i32, (ops i32imm), (ops)>;
+
+// The "u6" operand of a RRU6-type instruction
+let PrintMethod = "printU6" in {
+  def u6 : Operand<i32>, ImmLeaf<i32, [{
+    return isUInt<6>(Imm);
+  }]>;
+  def wide_u6 : Operand<i64>, ImmLeaf<i64, [{
+    return isUInt<6>(Imm);
+  }]>;
+}
+
 // ---------------------------------------------------------------------------
 // Selection DAG Nodes.
 // ---------------------------------------------------------------------------
@@ -299,14 +317,24 @@ def MOV_ru6 : F32_DOP_RU6<0b00100, 0b001010, 0,
 def cmov : PatFrag<(ops node:$op1, node:$op2, node:$cc),
                    (ARCcmov $op1, $op2, $cc)>;
 let Uses = [STATUS32] in {
-def MOVcc : F32_DOP_CC_RR<0b00100, 0b001010, 0,
-               (outs GPR32:$B),
-               (ins GPR32:$C, GPR32:$fval, cmovpred:$cc),
-               !strconcat("mov.", "$cc\t$B, $C"),
-               [(set GPR32:$B, (cmov i32:$C, i32:$fval, cmovpred:$cc))]> {
-  let Constraints = "$B = $fval";
-}
+  def MOVcc : F32_DOP_CC_RR<0b00100, 0b001010, 0,
+                 (outs GPR32:$B),
+                 (ins GPR32:$C, GPR32:$fval, cmovpred:$cc),
+                 !strconcat("mov.", "$cc\t$B, $C"),
+                 [(set GPR32:$B, (cmov i32:$C, i32:$fval, cmovpred:$cc))]> {
+    let Constraints = "$B = $fval";
+  }
+
+  def MOVcc_ru6 : F32_SOP_CC_RU6<0b00100, 0b001010, 0,
+                 (outs GPR32:$b), (ins u6:$c, CCOp:$cc, GPR32:$b2),
+                 "mov.$cc\t$b, $c", []> {
+    let isAsCheapAsAMove=0;
+    let isPredicable=1;
+    let isReMaterializable=0;
+    let Constraints="$b2 = $b";
+  }
 }
+
 def : Pat<(ARCGAWrapper tglobaladdr:$addr),
            (MOV_rlimm tglobaladdr:$addr)>;
 

diff  --git a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
index 611fd0e3e78dd..b7033d0972b9c 100644
--- a/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
+++ b/llvm/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
@@ -107,6 +107,9 @@ static DecodeStatus DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t,
 static DecodeStatus DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t,
                                              const void *);
 
+static DecodeStatus DecodeCCRU6Instruction(MCInst &, uint64_t, uint64_t,
+                                           const void *);
+
 static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t, uint64_t,
                                               const void *);
 
@@ -167,19 +170,19 @@ static DecodeStatus DecodeMEMrs9(MCInst &Inst, unsigned Insn, uint64_t Address,
 
 static bool DecodeSymbolicOperand(MCInst &Inst, uint64_t Address,
                                   uint64_t Value, const void *Decoder) {
-  static const uint64_t atLeast = 2;
+  static const uint64_t AtLeast = 2;
   // TODO: Try to force emitter to use MCDisassembler* instead of void*.
   auto Disassembler = static_cast<const MCDisassembler *>(Decoder);
   return (nullptr != Disassembler &&
           Disassembler->tryAddingSymbolicOperand(Inst, Value, Address, true, 0,
-                                                 atLeast));
+                                                 AtLeast));
 }
 
 static void DecodeSymbolicOperandOff(MCInst &Inst, uint64_t Address,
                                      uint64_t Offset, const void *Decoder) {
-  uint64_t nextAddress = Address + Offset;
+  uint64_t NextAddress = Address + Offset;
 
-  if (!DecodeSymbolicOperand(Inst, Address, nextAddress, Decoder))
+  if (!DecodeSymbolicOperand(Inst, Address, NextAddress, Decoder))
     Inst.addOperand(MCOperand::createImm(Offset));
 }
 
@@ -272,9 +275,9 @@ static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t Insn,
                                               const void *Decoder) {
   LLVM_DEBUG(dbgs() << "Decoding MOV_S h-register\n");
   using Field = decltype(Insn);
-  Field h = fieldFromInstruction(Insn, 5, 3) |
+  Field H = fieldFromInstruction(Insn, 5, 3) |
             (fieldFromInstruction(Insn, 0, 2) << 3);
-  Field g = fieldFromInstruction(Insn, 8, 3) |
+  Field G = fieldFromInstruction(Insn, 8, 3) |
             (fieldFromInstruction(Insn, 3, 2) << 3);
 
   auto DecodeRegisterOrImm = [&Inst, Address, Decoder](Field RegNum,
@@ -287,10 +290,25 @@ static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t Insn,
     return DecodeGPR32RegisterClass(Inst, RegNum, Address, Decoder);
   };
 
-  if (MCDisassembler::Success != DecodeRegisterOrImm(g, 0))
+  if (MCDisassembler::Success != DecodeRegisterOrImm(G, 0))
     return MCDisassembler::Fail;
 
-  return DecodeRegisterOrImm(h, Insn >> 16u);
+  return DecodeRegisterOrImm(H, Insn >> 16u);
+}
+
+static DecodeStatus DecodeCCRU6Instruction(MCInst &Inst, uint64_t Insn,
+                                           uint64_t Address,
+                                           const void *Decoder) {
+  unsigned DstB;
+  LLVM_DEBUG(dbgs() << "Decoding CCRU6 instruction:\n");
+  DstB = decodeBField(Insn);
+  DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder);
+  using Field = decltype(Insn);
+  Field U6Field = fieldFromInstruction(Insn, 6, 11);
+  Inst.addOperand(MCOperand::createImm(U6Field));
+  Field CCField = fieldFromInstruction(Insn, 0, 4);
+  Inst.addOperand(MCOperand::createImm(CCField));
+  return MCDisassembler::Success;
 }
 
 DecodeStatus ARCDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,

diff  --git a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp
index 8eefae5ee4911..f34b698e9af23 100644
--- a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp
+++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp
@@ -178,3 +178,30 @@ void ARCInstPrinter::printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum,
   assert(Op.isImm() && "Predicate operand is immediate.");
   O << ARCBRCondCodeToString((ARCCC::BRCondCode)Op.getImm());
 }
+
+void ARCInstPrinter::printCCOperand(const MCInst *MI, int OpNum,
+                                    raw_ostream &O) {
+  O << ARCCondCodeToString((ARCCC::CondCode)MI->getOperand(OpNum).getImm());
+}
+
+void ARCInstPrinter::printU6ShiftedBy(unsigned ShiftBy, const MCInst *MI,
+                                      int OpNum, raw_ostream &O) {
+  const MCOperand &MO = MI->getOperand(OpNum);
+  if (MO.isImm()) {
+    unsigned Value = MO.getImm();
+    unsigned Value2 = Value >> ShiftBy;
+    if (Value2 > 0x3F || (Value2 << ShiftBy != Value)) {
+      errs() << "!!! Instruction has out-of-range U6 immediate operand:\n"
+             << "    Opcode is " << MI->getOpcode() << "; operand value is "
+             << Value;
+      if (ShiftBy)
+        errs() << " scaled by " << (1 << ShiftBy) << "\n";
+      assert(false && "instruction has wrong format");
+    }
+  }
+  printOperand(MI, OpNum, O);
+}
+
+void ARCInstPrinter::printU6(const MCInst *MI, int OpNum, raw_ostream &O) {
+  printU6ShiftedBy(0, MI, OpNum, O);
+}

diff  --git a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h
index f6f8f9d089dfc..6f52e8faca3e9 100644
--- a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h
+++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h
@@ -33,6 +33,8 @@ class ARCInstPrinter : public MCInstPrinter {
   void printRegName(raw_ostream &OS, unsigned RegNo) const override;
   void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
                  const MCSubtargetInfo &STI, raw_ostream &O) override;
+  void printCCOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+  void printU6(const MCInst *MI, int OpNum, raw_ostream &O);
 
 private:
   void printMemOperandRI(const MCInst *MI, unsigned OpNum, raw_ostream &O);
@@ -44,6 +46,8 @@ class ARCInstPrinter : public MCInstPrinter {
   void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum,
                                  raw_ostream &O);
+  void printU6ShiftedBy(unsigned ShiftBy, const MCInst *MI, int OpNum,
+                        raw_ostream &O);
 };
 } // end namespace llvm
 


        


More information about the llvm-commits mailing list