Skip to content

Commit c3d9898

Browse files
committed
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351526 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 1f379ad commit c3d9898

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

lib/Target/AVR/AVRInstrInfo.td

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,22 @@ def imm0_63_neg : PatLeaf<(imm),
9090

9191
def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>;
9292

93+
// imm_com8_XFORM - Return the complement of a t2_so_imm value
94+
def imm_com8_XFORM : SDNodeXForm<imm, [{
95+
return CurDAG->getTargetConstant(~((uint8_t)N->getZExtValue()), SDLoc(N),
96+
MVT::i8);
97+
}]>;
98+
99+
// imm_com8 - Match an immediate that is a complement
100+
// of a 8-bit immediate.
101+
// Note: this pattern doesn't require an encoder method and such, as it's
102+
// only used on aliases (Pat<> and InstAlias<>). The actual encoding
103+
// is handled by the destination instructions, which use t2_so_imm.
104+
def imm_com8_asmoperand : AsmOperandClass { let Name = "ImmCom8"; }
105+
def imm_com8 : Operand<i8> {
106+
let ParserMatchClass = imm_com8_asmoperand;
107+
}
108+
93109
def ioaddr_XFORM : SDNodeXForm<imm,
94110
[{
95111
return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()) - 0x20, SDLoc(N), MVT::i8);
@@ -157,13 +173,6 @@ def memspi : Operand<iPTR>
157173
let MIOperandInfo = (ops GPRSP, i16imm);
158174
}
159175

160-
def imm_com8 : Operand<i8>
161-
{
162-
let EncoderMethod = "encodeComplement";
163-
164-
let MIOperandInfo = (ops i8imm);
165-
}
166-
167176
def relbrtarget_7 : Operand<OtherVT>
168177
{
169178
let PrintMethod = "printPCRelImm";
@@ -1729,20 +1738,7 @@ def BLD : FRdB<0b00,
17291738
"bld\t$rd, $b",
17301739
[]>;
17311740

1732-
// Set/clear bit in register operations.
1733-
let Constraints = "$src = $rd",
1734-
Defs = [SREG] in
1735-
{
1736-
// CBR Rd, K
1737-
// Alias for `ANDI Rd, COM(K)` where COM(K) is the complement of K.
1738-
// FIXME: This uses the 'complement' encoder. We need it to also use the
1739-
// imm_ldi8 encoder. This will cause no fixups to be created on this instruction.
1740-
def CBRRdK : FRdK<0b0111,
1741-
(outs LD8:$rd),
1742-
(ins LD8:$src, imm_com8:$k),
1743-
"cbr\t$rd, $k",
1744-
[]>;
1745-
}
1741+
def CBR : InstAlias<"cbr\t$rd, $k", (ANDIRdK LD8:$rd, imm_com8:$k), 0>;
17461742

17471743
// CLR Rd
17481744
// Alias for EOR Rd, Rd

lib/Target/AVR/AsmParser/AVRAsmParser.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,22 @@ class AVROperand : public MCParsedAsmOperand {
160160
addExpr(Inst, getImm());
161161
}
162162

163+
void addImmCom8Operands(MCInst &Inst, unsigned N) const {
164+
assert(N == 1 && "Invalid number of operands!");
165+
// The operand is actually a imm8, but we have its bitwise
166+
// negation in the assembly source, so twiddle it here.
167+
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
168+
Inst.addOperand(MCOperand::createImm(~(uint8_t)CE->getValue()));
169+
}
170+
171+
bool isImmCom8() const {
172+
if (!isImm()) return false;
173+
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
174+
if (!CE) return false;
175+
int64_t Value = CE->getValue();
176+
return isUInt<8>(Value);
177+
}
178+
163179
bool isReg() const { return Kind == k_Register; }
164180
bool isImm() const { return Kind == k_Immediate; }
165181
bool isToken() const { return Kind == k_Token; }

0 commit comments

Comments
 (0)