Skip to content

Commit f28f1c2

Browse files
authored
[AVR] Refactor ADIW/SBIW/MOVW instruction descriptions (NFCI) (#156876)
* Remove custom decoders for these instructions * Instead, provide decoders for DREGS/IWREGS register classes * Change register pair encodings to simplify instruction descriptions * Add/fix a few clarifying comments
1 parent 62f3452 commit f28f1c2

File tree

3 files changed

+54
-60
lines changed

3 files changed

+54
-60
lines changed

llvm/lib/Target/AVR/AVRInstrFormats.td

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -213,18 +213,16 @@ class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern>
213213
// MOVWRdRr special encoding: <|0000|0001|dddd|rrrr|>
214214
// d = destination = 4 bits
215215
// r = source = 4 bits
216-
// (Only accepts even registers)
216+
// (Only accepts register pairs)
217217
//===----------------------------------------------------------------------===//
218218
class FMOVWRdRr<dag outs, dag ins, string asmstr, list<dag> pattern>
219219
: AVRInst16<outs, ins, asmstr, pattern> {
220-
bits<5> rd;
221-
bits<5> rr;
220+
bits<4> rd;
221+
bits<4> rr;
222222

223223
let Inst{15 - 8} = 0b00000001;
224-
let Inst{7 - 4} = rd{4 - 1};
225-
let Inst{3 - 0} = rr{4 - 1};
226-
227-
let DecoderMethod = "decodeFMOVWRdRr";
224+
let Inst{7 - 4} = rd;
225+
let Inst{3 - 0} = rr;
228226
}
229227

230228
//===----------------------------------------------------------------------===//
@@ -292,16 +290,14 @@ class FFMULRdRr<bits<2> f, dag outs, dag ins, string asmstr, list<dag> pattern>
292290
//===----------------------------------------------------------------------===//
293291
class FWRdK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
294292
: AVRInst16<outs, ins, asmstr, pattern> {
295-
bits<5> rd; // accept 5 bits but only encode bits 1 and 2
293+
bits<2> rd;
296294
bits<6> k;
297295

298296
let Inst{15 - 9} = 0b1001011;
299297
let Inst{8} = f;
300298
let Inst{7 - 6} = k{5 - 4};
301-
let Inst{5 - 4} = rd{2 - 1};
299+
let Inst{5 - 4} = rd;
302300
let Inst{3 - 0} = k{3 - 0};
303-
304-
let DecoderMethod = "decodeFWRdK";
305301
}
306302

307303
//===----------------------------------------------------------------------===//

llvm/lib/Target/AVR/AVRRegisterInfo.td

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,33 +68,37 @@ def R31 : AVRReg<31, "r31", [], ["zh"]>, DwarfRegNum<[31]>;
6868
def SPL : AVRReg<32, "SPL">, DwarfRegNum<[32]>;
6969
def SPH : AVRReg<33, "SPH">, DwarfRegNum<[33]>;
7070

71+
// 16 bit GPR pairs.
7172
let SubRegIndices = [sub_lo, sub_hi], CoveredBySubRegs = 1 in {
72-
// 16 bit GPR pairs.
73-
def SP : AVRReg<32, "SP", [SPL, SPH]>, DwarfRegNum<[32]>;
73+
// The value 16 for the encoding is arbitrary. SP register is not encoded
74+
// into instructions, they use it implicitly depending on the opcode.
75+
def SP : AVRReg<16, "SP", [SPL, SPH]>, DwarfRegNum<[32]>;
7476

7577
// The pointer registers (X,Y,Z) are a special case because they
7678
// are printed as a `high:low` pair when a DREG is expected,
7779
// but printed using `X`, `Y`, `Z` when a pointer register is expected.
80+
// DREG registers are only used in ADIW, SBIW and MOVW instructions.
7881
let RegAltNameIndices = [ptr] in {
79-
def R31R30 : AVRReg<30, "r31:r30", [R30, R31], ["Z"]>, DwarfRegNum<[30]>;
80-
def R29R28 : AVRReg<28, "r29:r28", [R28, R29], ["Y"]>, DwarfRegNum<[28]>;
81-
def R27R26 : AVRReg<26, "r27:r26", [R26, R27], ["X"]>, DwarfRegNum<[26]>;
82+
def R31R30 : AVRReg<15, "r31:r30", [R30, R31], ["Z"]>, DwarfRegNum<[30]>;
83+
def R29R28 : AVRReg<14, "r29:r28", [R28, R29], ["Y"]>, DwarfRegNum<[28]>;
84+
def R27R26 : AVRReg<13, "r27:r26", [R26, R27], ["X"]>, DwarfRegNum<[26]>;
8285
}
83-
def R25R24 : AVRReg<24, "r25:r24", [R24, R25]>, DwarfRegNum<[24]>;
84-
def R23R22 : AVRReg<22, "r23:r22", [R22, R23]>, DwarfRegNum<[22]>;
85-
def R21R20 : AVRReg<20, "r21:r20", [R20, R21]>, DwarfRegNum<[20]>;
86-
def R19R18 : AVRReg<18, "r19:r18", [R18, R19]>, DwarfRegNum<[18]>;
87-
def R17R16 : AVRReg<16, "r17:r16", [R16, R17]>, DwarfRegNum<[16]>;
88-
def R15R14 : AVRReg<14, "r15:r14", [R14, R15]>, DwarfRegNum<[14]>;
89-
def R13R12 : AVRReg<12, "r13:r12", [R12, R13]>, DwarfRegNum<[12]>;
90-
def R11R10 : AVRReg<10, "r11:r10", [R10, R11]>, DwarfRegNum<[10]>;
91-
def R9R8 : AVRReg<8, "r9:r8", [R8, R9]>, DwarfRegNum<[8]>;
92-
def R7R6 : AVRReg<6, "r7:r6", [R6, R7]>, DwarfRegNum<[6]>;
93-
def R5R4 : AVRReg<4, "r5:r4", [R4, R5]>, DwarfRegNum<[4]>;
94-
def R3R2 : AVRReg<2, "r3:r2", [R2, R3]>, DwarfRegNum<[2]>;
86+
def R25R24 : AVRReg<12, "r25:r24", [R24, R25]>, DwarfRegNum<[24]>;
87+
def R23R22 : AVRReg<11, "r23:r22", [R22, R23]>, DwarfRegNum<[22]>;
88+
def R21R20 : AVRReg<10, "r21:r20", [R20, R21]>, DwarfRegNum<[20]>;
89+
def R19R18 : AVRReg<9, "r19:r18", [R18, R19]>, DwarfRegNum<[18]>;
90+
def R17R16 : AVRReg<8, "r17:r16", [R16, R17]>, DwarfRegNum<[16]>;
91+
def R15R14 : AVRReg<7, "r15:r14", [R14, R15]>, DwarfRegNum<[14]>;
92+
def R13R12 : AVRReg<6, "r13:r12", [R12, R13]>, DwarfRegNum<[12]>;
93+
def R11R10 : AVRReg<5, "r11:r10", [R10, R11]>, DwarfRegNum<[10]>;
94+
def R9R8 : AVRReg<4, "r9:r8", [R8, R9]>, DwarfRegNum<[8]>;
95+
def R7R6 : AVRReg<3, "r7:r6", [R6, R7]>, DwarfRegNum<[6]>;
96+
def R5R4 : AVRReg<2, "r5:r4", [R4, R5]>, DwarfRegNum<[4]>;
97+
def R3R2 : AVRReg<1, "r3:r2", [R2, R3]>, DwarfRegNum<[2]>;
9598
def R1R0 : AVRReg<0, "r1:r0", [R0, R1]>, DwarfRegNum<[0]>;
9699

97-
// Pseudo registers for unaligned i16
100+
// Pseudo registers for unaligned i16. These are only used in pseudo
101+
// instructions, so encoding values are arbitrary.
98102
def R26R25 : AVRReg<25, "r26:r25", [R25, R26]>, DwarfRegNum<[25]>;
99103
def R24R23 : AVRReg<23, "r24:r23", [R23, R24]>, DwarfRegNum<[23]>;
100104
def R22R21 : AVRReg<21, "r22:r21", [R21, R22]>, DwarfRegNum<[21]>;

llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,21 @@ LLVMInitializeAVRDisassembler() {
6161
createAVRDisassembler);
6262
}
6363

64-
static const uint16_t GPRDecoderTable[] = {
64+
static constexpr MCRegister GPRDecoderTable[] = {
6565
AVR::R0, AVR::R1, AVR::R2, AVR::R3, AVR::R4, AVR::R5, AVR::R6,
6666
AVR::R7, AVR::R8, AVR::R9, AVR::R10, AVR::R11, AVR::R12, AVR::R13,
6767
AVR::R14, AVR::R15, AVR::R16, AVR::R17, AVR::R18, AVR::R19, AVR::R20,
6868
AVR::R21, AVR::R22, AVR::R23, AVR::R24, AVR::R25, AVR::R26, AVR::R27,
6969
AVR::R28, AVR::R29, AVR::R30, AVR::R31,
7070
};
7171

72+
static constexpr MCRegister GPRPairDecoderTable[] = {
73+
AVR::R1R0, AVR::R3R2, AVR::R5R4, AVR::R7R6,
74+
AVR::R9R8, AVR::R11R10, AVR::R13R12, AVR::R15R14,
75+
AVR::R17R16, AVR::R19R18, AVR::R21R20, AVR::R23R22,
76+
AVR::R25R24, AVR::R27R26, AVR::R29R28, AVR::R31R30,
77+
};
78+
7279
static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
7380
uint64_t Address,
7481
const MCDisassembler *Decoder) {
@@ -98,6 +105,23 @@ static DecodeStatus DecodeLD8loRegisterClass(MCInst &Inst, unsigned RegNo,
98105
return MCDisassembler::Success;
99106
}
100107

108+
static DecodeStatus DecodeDREGSRegisterClass(MCInst &Inst, unsigned RegNo,
109+
uint64_t Address,
110+
const MCDisassembler *Decoder) {
111+
assert(isUInt<4>(RegNo));
112+
Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo]));
113+
return MCDisassembler::Success;
114+
}
115+
116+
static DecodeStatus DecodeIWREGSRegisterClass(MCInst &Inst, unsigned RegNo,
117+
uint64_t Address,
118+
const MCDisassembler *Decoder) {
119+
assert(isUInt<2>(RegNo));
120+
// Only AVR::R25R24, AVR::R27R26, AVR::R29R28, AVR::R31R30 are legal.
121+
Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[12 + RegNo]));
122+
return MCDisassembler::Success;
123+
}
124+
101125
static DecodeStatus DecodeZREGRegisterClass(MCInst &Inst,
102126
const MCDisassembler *Decoder) {
103127
Inst.addOperand(MCOperand::createReg(AVR::R31R30));
@@ -129,36 +153,6 @@ static DecodeStatus decodeRelCondBrTarget13(MCInst &Inst, unsigned Field,
129153
return MCDisassembler::Success;
130154
}
131155

132-
static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
133-
uint64_t Address,
134-
const MCDisassembler *Decoder) {
135-
unsigned r = fieldFromInstruction(Insn, 4, 4) * 2;
136-
unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
137-
if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
138-
MCDisassembler::Fail)
139-
return MCDisassembler::Fail;
140-
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
141-
MCDisassembler::Fail)
142-
return MCDisassembler::Fail;
143-
return MCDisassembler::Success;
144-
}
145-
146-
static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
147-
const MCDisassembler *Decoder) {
148-
unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25
149-
unsigned k = 0;
150-
k |= fieldFromInstruction(Insn, 0, 4);
151-
k |= fieldFromInstruction(Insn, 6, 2) << 4;
152-
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
153-
MCDisassembler::Fail)
154-
return MCDisassembler::Fail;
155-
if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
156-
MCDisassembler::Fail)
157-
return MCDisassembler::Fail;
158-
Inst.addOperand(MCOperand::createImm(k));
159-
return MCDisassembler::Success;
160-
}
161-
162156
static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
163157
const MCDisassembler *Decoder) {
164158
// As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory

0 commit comments

Comments
 (0)