Skip to content

Commit 295cdd5

Browse files
[ARM][TableGen][MC] Change the ARM mnemonic operands to be optional for ASM parsing (#83436)
This changs the way the assembly matcher works for Aarch32 parsing. Previously there was a pile of hacks which dictated whether the CC, CCOut, and VCC operands should be present which de-facto chose if the wide/narrow (or thumb1/thumb2/arm) instruction version were chosen. This meant much of the TableGen machinery present for the assembly matching was effectively being bypassed and worked around. This patch makes the CC and CCOut operands optional which allows the ASM matcher operate as it was designed and means we can avoid doing some of the hacks done previously. This also adds the option for the target to allow the prioritizing the smaller instruction encodings as is required for Aarch32.
1 parent 3e6db60 commit 295cdd5

28 files changed

+1343
-1135
lines changed

llvm/include/llvm/Target/Target.td

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -947,8 +947,6 @@ class AsmOperandClass {
947947
/// instruction if it hasn't matched all the operands yet. However, this
948948
/// error will be suppressed if all of the remaining unmatched operands are
949949
/// marked as IsOptional.
950-
///
951-
/// Optional arguments must be at the end of the operand list.
952950
bit IsOptional = false;
953951

954952
/// The name of the method on the target specific asm parser that returns the

llvm/lib/Target/ARM/ARM.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,7 @@ def ARMAsmWriter : AsmWriter {
17421742

17431743
def ARMAsmParser : AsmParser {
17441744
bit ReportMultipleNearMisses = 1;
1745+
let PreferSmallerInstructions = true;
17451746
}
17461747

17471748
def ARMAsmParserVariant : AsmParserVariant {

llvm/lib/Target/ARM/ARMInstrFormats.td

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ def iflags_op : Operand<i32> {
155155

156156
// ARM Predicate operand. Default to 14 = always (AL). Second part is CC
157157
// register whose default is 0 (no register).
158-
def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
158+
def CondCodeOperand : AsmOperandClass {
159+
let Name = "CondCode";
160+
let DefaultMethod = "defaultCondCodeOp";
161+
let IsOptional = true;
162+
}
159163
def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm),
160164
(ops (i32 14), (i32 zero_reg))> {
161165
let PrintMethod = "printPredicateOperand";
@@ -174,7 +178,11 @@ def cmovpred : Operand<i32>, PredicateOp,
174178
}
175179

176180
// Conditional code result for instructions whose 's' bit is set, e.g. subs.
177-
def CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
181+
def CCOutOperand : AsmOperandClass {
182+
let Name = "CCOut";
183+
let DefaultMethod = "defaultCCOutOp";
184+
let IsOptional = true;
185+
}
178186
def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
179187
let EncoderMethod = "getCCOutOpValue";
180188
let PrintMethod = "printSBitModifierOperand";
@@ -202,10 +210,14 @@ def inv_cond_XFORM : SDNodeXForm<imm, [{
202210
def VPTPredNOperand : AsmOperandClass {
203211
let Name = "VPTPredN";
204212
let PredicateMethod = "isVPTPred";
213+
let DefaultMethod = "defaultVPTPredOp";
214+
let IsOptional = true;
205215
}
206216
def VPTPredROperand : AsmOperandClass {
207217
let Name = "VPTPredR";
208218
let PredicateMethod = "isVPTPred";
219+
let DefaultMethod = "defaultVPTPredOp";
220+
let IsOptional = true;
209221
}
210222

211223
// Operand classes for the cluster of MC operands describing a
@@ -468,7 +480,7 @@ class InstThumb<AddrMode am, int sz, IndexMode im,
468480
// These are aliases that require C++ handling to convert to the target
469481
// instruction, while InstAliases can be handled directly by tblgen.
470482
class AsmPseudoInst<string asm, dag iops, dag oops = (outs)>
471-
: InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
483+
: InstTemplate<AddrModeNone, 4, IndexModeNone, Pseudo, GenericDomain,
472484
"", NoItinerary> {
473485
let OutOperandList = oops;
474486
let InOperandList = iops;

llvm/lib/Target/ARM/ARMInstrThumb.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255_expr:$imm8), IIC_iMOVi,
12101210
// Because we have an explicit tMOVSr below, we need an alias to handle
12111211
// the immediate "movs" form here. Blech.
12121212
def : tInstAlias <"movs $Rdn, $imm8",
1213-
(tMOVi8 tGPR:$Rdn, CPSR, imm0_255_expr:$imm8, 14, 0)>;
1213+
(tMOVi8 tGPR:$Rdn, CPSR, imm0_255_expr:$imm8, 14, zero_reg)>;
12141214

12151215
// A7-73: MOV(2) - mov setting flag.
12161216

@@ -1768,7 +1768,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
17681768

17691769
// In Thumb1, "nop" is encoded as a "mov r8, r8". Technically, the bf00
17701770
// encoding is available on ARMv6K, but we don't differentiate that finely.
1771-
def : InstAlias<"nop", (tMOVr R8, R8, 14, 0), 0>, Requires<[IsThumb, IsThumb1Only]>;
1771+
def : InstAlias<"nop", (tMOVr R8, R8, 14, zero_reg), 0>, Requires<[IsThumb, IsThumb1Only]>;
17721772

17731773

17741774
// "neg" is and alias for "rsb rd, rn, #0"

llvm/lib/Target/ARM/ARMInstrThumb2.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5092,14 +5092,14 @@ def : InstAlias<"dmb${p}.w", (t2DMB 0xf, pred:$p), 0>, Requires<[HasDB]>;
50925092
def : InstAlias<"dsb${p}.w\t$opt", (t2DSB memb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
50935093
def : InstAlias<"dsb${p}", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
50945094
def : InstAlias<"dsb${p}.w", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
5095-
def : InstAlias<"isb${p}.w\t$opt", (t2ISB memb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
5095+
def : InstAlias<"isb${p}.w\t$opt", (t2ISB instsyncb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
50965096
def : InstAlias<"isb${p}", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;
50975097
def : InstAlias<"isb${p}.w", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;
50985098

5099-
// Non-predicable aliases of a predicable DSB: the predicate is (14, 0) where
5100-
// 14 = AL (always execute) and 0 = "instruction doesn't read the CPSR".
5101-
def : InstAlias<"ssbb", (t2DSB 0x0, 14, 0), 1>, Requires<[HasDB, IsThumb2]>;
5102-
def : InstAlias<"pssbb", (t2DSB 0x4, 14, 0), 1>, Requires<[HasDB, IsThumb2]>;
5099+
// Non-predicable aliases of a predicable DSB: the predicate is (14, zero_reg) where
5100+
// 14 = AL (always execute) and zero_reg = "instruction doesn't read the CPSR".
5101+
def : InstAlias<"ssbb", (t2DSB 0x0, 14, zero_reg), 1>, Requires<[HasDB, IsThumb2]>;
5102+
def : InstAlias<"pssbb", (t2DSB 0x4, 14, zero_reg), 1>, Requires<[HasDB, IsThumb2]>;
51035103

51045104
// Armv8-R 'Data Full Barrier'
51055105
def : InstAlias<"dfb${p}", (t2DSB 0xc, pred:$p), 1>, Requires<[HasDFB]>;

0 commit comments

Comments
 (0)