llvm.org GIT mirror llvm / c3d9898
[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 Dylan McKay 1 year, 10 months ago
2 changed file(s) with 33 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
8989
9090 def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>;
9191
92 // imm_com8_XFORM - Return the complement of a t2_so_imm value
93 def imm_com8_XFORM : SDNodeXForm
94 return CurDAG->getTargetConstant(~((uint8_t)N->getZExtValue()), SDLoc(N),
95 MVT::i8);
96 }]>;
97
98 // imm_com8 - Match an immediate that is a complement
99 // of a 8-bit immediate.
100 // Note: this pattern doesn't require an encoder method and such, as it's
101 // only used on aliases (Pat<> and InstAlias<>). The actual encoding
102 // is handled by the destination instructions, which use t2_so_imm.
103 def imm_com8_asmoperand : AsmOperandClass { let Name = "ImmCom8"; }
104 def imm_com8 : Operand {
105 let ParserMatchClass = imm_com8_asmoperand;
106 }
107
92108 def ioaddr_XFORM : SDNodeXForm
93109 [{
94110 return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()) - 0x20, SDLoc(N), MVT::i8);
154170 def memspi : Operand
155171 {
156172 let MIOperandInfo = (ops GPRSP, i16imm);
157 }
158
159 def imm_com8 : Operand
160 {
161 let EncoderMethod = "encodeComplement";
162
163 let MIOperandInfo = (ops i8imm);
164173 }
165174
166175 def relbrtarget_7 : Operand
17281737 "bld\t$rd, $b",
17291738 []>;
17301739
1731 // Set/clear bit in register operations.
1732 let Constraints = "$src = $rd",
1733 Defs = [SREG] in
1734 {
1735 // CBR Rd, K
1736 // Alias for `ANDI Rd, COM(K)` where COM(K) is the complement of K.
1737 // FIXME: This uses the 'complement' encoder. We need it to also use the
1738 // imm_ldi8 encoder. This will cause no fixups to be created on this instruction.
1739 def CBRRdK : FRdK<0b0111,
1740 (outs LD8:$rd),
1741 (ins LD8:$src, imm_com8:$k),
1742 "cbr\t$rd, $k",
1743 []>;
1744 }
1740 def CBR : InstAlias<"cbr\t$rd, $k", (ANDIRdK LD8:$rd, imm_com8:$k), 0>;
17451741
17461742 // CLR Rd
17471743 // Alias for EOR Rd, Rd
157157
158158 Inst.addOperand(MCOperand::createReg(getReg()));
159159 addExpr(Inst, getImm());
160 }
161
162 void addImmCom8Operands(MCInst &Inst, unsigned N) const {
163 assert(N == 1 && "Invalid number of operands!");
164 // The operand is actually a imm8, but we have its bitwise
165 // negation in the assembly source, so twiddle it here.
166 const MCConstantExpr *CE = dyn_cast(getImm());
167 Inst.addOperand(MCOperand::createImm(~(uint8_t)CE->getValue()));
168 }
169
170 bool isImmCom8() const {
171 if (!isImm()) return false;
172 const MCConstantExpr *CE = dyn_cast(getImm());
173 if (!CE) return false;
174 int64_t Value = CE->getValue();
175 return isUInt<8>(Value);
160176 }
161177
162178 bool isReg() const { return Kind == k_Register; }