[llvm] r351526 - [AVR] Rewrite the CBRRdK instruction as an alias of ANDIRdK

Dylan McKay via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 17 23:31:34 PST 2019


Author: dylanmckay
Date: Thu Jan 17 23:31:34 2019
New Revision: 351526

URL: http://llvm.org/viewvc/llvm-project?rev=351526&view=rev
Log:
[AVR] Rewrite the CBRRdK instruction as an alias of ANDIRdK

The CBR instruction is just an ANDI instruction with the immediate
complemented.

Because of this, prior to this change TableGen would warn due to a
decoding conflict.

This commit fixes the existing compilation warning:

  ===============
  [423/492] Building AVRGenDisassemblerTables.inc...
  Decoding Conflict:
                  0111............
                  01..............
                  ................
          ANDIRdK 0111____________
          CBRRdK 0111____________
  ================

After this commit, there are no more decoding conflicts in the AVR
backend's instruction definitions.

Thanks to Eli F for pointing me torward `t2_so_imm_not` as an example of
how to perform a complement in an instruction alias.

Fixes BugZilla PR38802.

Modified:
    llvm/trunk/lib/Target/AVR/AVRInstrInfo.td
    llvm/trunk/lib/Target/AVR/AsmParser/AVRAsmParser.cpp

Modified: llvm/trunk/lib/Target/AVR/AVRInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRInstrInfo.td?rev=351526&r1=351525&r2=351526&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRInstrInfo.td (original)
+++ llvm/trunk/lib/Target/AVR/AVRInstrInfo.td Thu Jan 17 23:31:34 2019
@@ -90,6 +90,22 @@ def imm0_63_neg : PatLeaf<(imm),
 
 def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>;
 
+// imm_com8_XFORM - Return the complement of a t2_so_imm value
+def imm_com8_XFORM : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(~((uint8_t)N->getZExtValue()), SDLoc(N),
+                                   MVT::i8);
+}]>;
+
+// imm_com8 - Match an immediate that is a complement
+// of a 8-bit immediate.
+// Note: this pattern doesn't require an encoder method and such, as it's
+// only used on aliases (Pat<> and InstAlias<>). The actual encoding
+// is handled by the destination instructions, which use t2_so_imm.
+def imm_com8_asmoperand : AsmOperandClass { let Name = "ImmCom8"; }
+def imm_com8 : Operand<i8> {
+  let ParserMatchClass = imm_com8_asmoperand;
+}
+
 def ioaddr_XFORM : SDNodeXForm<imm,
 [{
   return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()) - 0x20, SDLoc(N), MVT::i8);
@@ -157,13 +173,6 @@ def memspi : Operand<iPTR>
   let MIOperandInfo = (ops GPRSP, i16imm);
 }
 
-def imm_com8 : Operand<i8>
-{
-  let EncoderMethod = "encodeComplement";
-
-  let MIOperandInfo = (ops i8imm);
-}
-
 def relbrtarget_7 : Operand<OtherVT>
 {
     let PrintMethod   = "printPCRelImm";
@@ -1729,20 +1738,7 @@ def BLD : FRdB<0b00,
                "bld\t$rd, $b",
                []>;
 
-// Set/clear bit in register operations.
-let Constraints = "$src = $rd",
-Defs = [SREG] in
-{
-  // CBR Rd, K
-  // Alias for `ANDI Rd, COM(K)` where COM(K) is the complement of K.
-  // FIXME: This uses the 'complement' encoder. We need it to also use the
-  // imm_ldi8 encoder. This will cause no fixups to be created on this instruction.
-  def CBRRdK : FRdK<0b0111,
-                    (outs LD8:$rd),
-                    (ins LD8:$src, imm_com8:$k),
-                    "cbr\t$rd, $k",
-                    []>;
-}
+def CBR : InstAlias<"cbr\t$rd, $k", (ANDIRdK LD8:$rd, imm_com8:$k), 0>;
 
 // CLR Rd
 // Alias for EOR Rd, Rd

Modified: llvm/trunk/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AsmParser/AVRAsmParser.cpp?rev=351526&r1=351525&r2=351526&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AsmParser/AVRAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AVR/AsmParser/AVRAsmParser.cpp Thu Jan 17 23:31:34 2019
@@ -160,6 +160,22 @@ public:
     addExpr(Inst, getImm());
   }
 
+  void addImmCom8Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    // The operand is actually a imm8, but we have its bitwise
+    // negation in the assembly source, so twiddle it here.
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    Inst.addOperand(MCOperand::createImm(~(uint8_t)CE->getValue()));
+  }
+
+  bool isImmCom8() const {
+    if (!isImm()) return false;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+    return isUInt<8>(Value);
+  }
+
   bool isReg() const { return Kind == k_Register; }
   bool isImm() const { return Kind == k_Immediate; }
   bool isToken() const { return Kind == k_Token; }




More information about the llvm-commits mailing list