diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td index 5720af7d8df6..fffa66faa8c8 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -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 : SDNodeXFormgetTargetConstant(~((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 { + let ParserMatchClass = imm_com8_asmoperand; +} + def ioaddr_XFORM : SDNodeXFormgetTargetConstant(uint8_t(N->getZExtValue()) - 0x20, SDLoc(N), MVT::i8); @@ -157,13 +173,6 @@ def memspi : Operand let MIOperandInfo = (ops GPRSP, i16imm); } -def imm_com8 : Operand -{ - let EncoderMethod = "encodeComplement"; - - let MIOperandInfo = (ops i8imm); -} - def relbrtarget_7 : Operand { 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 diff --git a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp index f2bb59265271..f496dea64d16 100644 --- a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp +++ b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp @@ -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(getImm()); + Inst.addOperand(MCOperand::createImm(~(uint8_t)CE->getValue())); + } + + bool isImmCom8() const { + if (!isImm()) return false; + const MCConstantExpr *CE = dyn_cast(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; }