Skip to content

Commit 7cbcde4

Browse files
committed
[M68k] Use separate asm operand class for different widths of address
This could help asm parser to pick the correct variant of instruction. This patch also migrated all the control instructions MC tests.
1 parent cf277f0 commit 7cbcde4

File tree

8 files changed

+178
-280
lines changed

8 files changed

+178
-280
lines changed

llvm/lib/Target/M68k/AsmParser/M68kAsmParser.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class M68kOperand : public MCParsedAsmOperand {
133133
M68kMemOp MemOp;
134134
};
135135

136+
template <unsigned N> bool isAddrN() const;
137+
136138
public:
137139
M68kOperand(enum Kind Kind, SMLoc Start, SMLoc End)
138140
: Base(), Kind(Kind), Start(Start), End(End) {}
@@ -172,6 +174,9 @@ class M68kOperand : public MCParsedAsmOperand {
172174

173175
// Addr
174176
bool isAddr() const;
177+
bool isAddr8() const { return isAddrN<8>(); }
178+
bool isAddr16() const { return isAddrN<16>(); }
179+
bool isAddr32() const { return isAddrN<32>(); }
175180
void addAddrOperands(MCInst &Inst, unsigned N) const;
176181

177182
// ARI
@@ -306,6 +311,17 @@ std::unique_ptr<M68kOperand> M68kOperand::createImm(const MCExpr *Expr,
306311
bool M68kOperand::isAddr() const {
307312
return isMemOp() && MemOp.Op == M68kMemOp::Kind::Addr;
308313
}
314+
// TODO: Maybe we can also store the size of OuterDisp
315+
// in Size?
316+
template <unsigned N> bool M68kOperand::isAddrN() const {
317+
if (isAddr()) {
318+
int64_t Res;
319+
if (MemOp.OuterDisp->evaluateAsAbsolute(Res))
320+
return isInt<N>(Res);
321+
return true;
322+
}
323+
return false;
324+
}
309325
void M68kOperand::addAddrOperands(MCInst &Inst, unsigned N) const {
310326
M68kOperand::addExpr(Inst, MemOp.OuterDisp);
311327
}

llvm/lib/Target/M68k/M68kInstrInfo.td

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,11 @@ def MxSize8 : MxSize<8, "b", "byte">;
165165
def MxSize16 : MxSize<16, "w", "word">;
166166
def MxSize32 : MxSize<32, "l", "long">;
167167

168-
class MxOpClass<string name> : AsmOperandClass {
168+
class MxOpClass<string name,
169+
list<AsmOperandClass> superClasses = []> : AsmOperandClass {
169170
let Name = name;
170171
let ParserMethod = "parseMemOp";
172+
let SuperClasses = superClasses;
171173
}
172174

173175
def MxRegClass : MxOpClass<"Reg">;
@@ -176,7 +178,7 @@ def MxRegClass : MxOpClass<"Reg">;
176178
// both ADD32dd and ADD32dr has {MCK_RegClass, MCK_RegClass} for
177179
// their operands, which makes AsmParser unable to pick the correct
178180
// one in a deterministic way.
179-
let RenderMethod = "addRegOperands", SuperClasses = [MxRegClass] in {
181+
let RenderMethod = "addRegOperands", SuperClasses = [MxRegClass]in {
180182
def MxARegClass : MxOpClass<"AReg">;
181183
def MxDRegClass : MxOpClass<"DReg">;
182184
}
@@ -317,19 +319,27 @@ def MxARII32_TC : MxMemOp<(ops i8imm, AR32_TC, XR32_TC), MxSize32, "f", "printA
317319
// extended before it is used. The reference is classified as a data reference
318320
// with the exception of the jump and jump-tosubroutine instructions.
319321
def MxAddr : MxOpClass<"Addr">;
320-
def MxAS8 : MxMemOp<(ops OtherVT), MxSize8, "B", "printAS8Mem", MxAddr>;
321-
def MxAS16 : MxMemOp<(ops OtherVT), MxSize16, "B", "printAS16Mem", MxAddr>;
322-
def MxAS32 : MxMemOp<(ops OtherVT), MxSize32, "B", "printAS32Mem", MxAddr>;
322+
let RenderMethod = "addAddrOperands" in {
323+
// This hierarchy ensures Addr8 will always be parsed
324+
// before other larger-width variants.
325+
def MxAddr32 : MxOpClass<"Addr32", [MxAddr]>;
326+
def MxAddr16 : MxOpClass<"Addr16", [MxAddr32]>;
327+
def MxAddr8 : MxOpClass<"Addr8", [MxAddr16]>;
328+
}
329+
330+
def MxAS8 : MxMemOp<(ops OtherVT), MxSize8, "B", "printAS8Mem", MxAddr8>;
331+
def MxAS16 : MxMemOp<(ops OtherVT), MxSize16, "B", "printAS16Mem", MxAddr16>;
332+
def MxAS32 : MxMemOp<(ops OtherVT), MxSize32, "B", "printAS32Mem", MxAddr32>;
323333

324334
// ABSOLUTE LONG ADDRESS. This addressing mode requires two words of extension.
325335
// The address of the operand is developed by the concatenation of the extension
326336
// words. The high order part of the address is the first extension word; the low
327337
// order part of the address is the second extension word. The reference is
328338
// classified as a data reference with the exception of the jump and jump
329339
// to-subroutine instructions.
330-
def MxAL8 : MxMemOp<(ops OtherVT), MxSize8, "b", "printAL8Mem", MxAddr>;
331-
def MxAL16 : MxMemOp<(ops OtherVT), MxSize16, "b", "printAL16Mem", MxAddr>;
332-
def MxAL32 : MxMemOp<(ops OtherVT), MxSize32, "b", "printAL32Mem", MxAddr>;
340+
def MxAL8 : MxMemOp<(ops OtherVT), MxSize8, "b", "printAL8Mem", MxAddr8>;
341+
def MxAL16 : MxMemOp<(ops OtherVT), MxSize16, "b", "printAL16Mem", MxAddr16>;
342+
def MxAL32 : MxMemOp<(ops OtherVT), MxSize32, "b", "printAL32Mem", MxAddr32>;
333343

334344
def MxPCD : MxOpClass<"PCD">;
335345
def MxPCI : MxOpClass<"PCI">;
@@ -383,16 +393,15 @@ def Mxi16imm : MxOp<i16, MxSize16, "i">;
383393
def Mxi32imm : MxOp<i32, MxSize32, "i">;
384394
} // OPERAND_IMMEDIATE
385395

386-
let OperandType = "OPERAND_PCREL",
387-
ParserMatchClass = MxAddr,
388-
PrintMethod = "printPCRelImm" in {
389-
396+
class MxBrTargetOperand<int N> : Operand<OtherVT> {
397+
let OperandType = "OPERAND_PCREL";
398+
let PrintMethod = "printPCRelImm";
399+
let ParserMatchClass = !cast<AsmOperandClass>("MxAddr"#N);
400+
}
390401
// Branch targets have OtherVT type and print as pc-relative values.
391-
def MxBrTarget8 : Operand<OtherVT>;
392-
def MxBrTarget16 : Operand<OtherVT>;
393-
def MxBrTarget32 : Operand<OtherVT>;
394-
395-
} // OPERAND_PCREL
402+
def MxBrTarget8 : MxBrTargetOperand<8>;
403+
def MxBrTarget16 : MxBrTargetOperand<16>;
404+
def MxBrTarget32 : MxBrTargetOperand<32>;
396405

397406
// Used with MOVEM
398407
def MxMoveMask : MxOp<i16, MxSize16, "m"> {

llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBRA.mir

Lines changed: 0 additions & 49 deletions
This file was deleted.

llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBcc.mir

Lines changed: 0 additions & 126 deletions
This file was deleted.

llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxCALL.mir

Lines changed: 0 additions & 88 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: llvm-mc -triple=m68k -motorola-integers -show-encoding %s | FileCheck %s
2+
3+
; CHECK: bra $1
4+
; CHECK-SAME: encoding: [0x60,0x01]
5+
bra $1
6+
; CHECK: bra $2a
7+
; CHECK-SAME: encoding: [0x60,0x2a]
8+
bra $2a
9+
; CHECK: bra $3fc
10+
; CHECK-SAME: encoding: [0x60,0x00,0x03,0xfc]
11+
bra $3fc
12+

0 commit comments

Comments
 (0)