forked from OSchip/llvm-project
[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. llvm-svn: 351526
This commit is contained in:
parent
66609a8255
commit
d770da9834
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue