Skip to content

Commit

Permalink
[ARM][TableGen][MC] Change the ARM mnemonic operands to be optional f…
Browse files Browse the repository at this point in the history
…or 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.
  • Loading branch information
AlfieRichardsArm committed Mar 18, 2024
1 parent 3e6db60 commit 295cdd5
Show file tree
Hide file tree
Showing 28 changed files with 1,343 additions and 1,135 deletions.
2 changes: 0 additions & 2 deletions llvm/include/llvm/Target/Target.td
Expand Up @@ -947,8 +947,6 @@ class AsmOperandClass {
/// instruction if it hasn't matched all the operands yet. However, this
/// error will be suppressed if all of the remaining unmatched operands are
/// marked as IsOptional.
///
/// Optional arguments must be at the end of the operand list.
bit IsOptional = false;

/// The name of the method on the target specific asm parser that returns the
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/ARM/ARM.td
Expand Up @@ -1742,6 +1742,7 @@ def ARMAsmWriter : AsmWriter {

def ARMAsmParser : AsmParser {
bit ReportMultipleNearMisses = 1;
let PreferSmallerInstructions = true;
}

def ARMAsmParserVariant : AsmParserVariant {
Expand Down
18 changes: 15 additions & 3 deletions llvm/lib/Target/ARM/ARMInstrFormats.td
Expand Up @@ -155,7 +155,11 @@ def iflags_op : Operand<i32> {

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

// Conditional code result for instructions whose 's' bit is set, e.g. subs.
def CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
def CCOutOperand : AsmOperandClass {
let Name = "CCOut";
let DefaultMethod = "defaultCCOutOp";
let IsOptional = true;
}
def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
let EncoderMethod = "getCCOutOpValue";
let PrintMethod = "printSBitModifierOperand";
Expand Down Expand Up @@ -202,10 +210,14 @@ def inv_cond_XFORM : SDNodeXForm<imm, [{
def VPTPredNOperand : AsmOperandClass {
let Name = "VPTPredN";
let PredicateMethod = "isVPTPred";
let DefaultMethod = "defaultVPTPredOp";
let IsOptional = true;
}
def VPTPredROperand : AsmOperandClass {
let Name = "VPTPredR";
let PredicateMethod = "isVPTPred";
let DefaultMethod = "defaultVPTPredOp";
let IsOptional = true;
}

// Operand classes for the cluster of MC operands describing a
Expand Down Expand Up @@ -468,7 +480,7 @@ class InstThumb<AddrMode am, int sz, IndexMode im,
// These are aliases that require C++ handling to convert to the target
// instruction, while InstAliases can be handled directly by tblgen.
class AsmPseudoInst<string asm, dag iops, dag oops = (outs)>
: InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
: InstTemplate<AddrModeNone, 4, IndexModeNone, Pseudo, GenericDomain,
"", NoItinerary> {
let OutOperandList = oops;
let InOperandList = iops;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/ARM/ARMInstrThumb.td
Expand Up @@ -1210,7 +1210,7 @@ def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255_expr:$imm8), IIC_iMOVi,
// Because we have an explicit tMOVSr below, we need an alias to handle
// the immediate "movs" form here. Blech.
def : tInstAlias <"movs $Rdn, $imm8",
(tMOVi8 tGPR:$Rdn, CPSR, imm0_255_expr:$imm8, 14, 0)>;
(tMOVi8 tGPR:$Rdn, CPSR, imm0_255_expr:$imm8, 14, zero_reg)>;

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

Expand Down Expand Up @@ -1768,7 +1768,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {

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


// "neg" is and alias for "rsb rd, rn, #0"
Expand Down
10 changes: 5 additions & 5 deletions llvm/lib/Target/ARM/ARMInstrThumb2.td
Expand Up @@ -5092,14 +5092,14 @@ def : InstAlias<"dmb${p}.w", (t2DMB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"dsb${p}.w\t$opt", (t2DSB memb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"dsb${p}", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"dsb${p}.w", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}.w\t$opt", (t2ISB memb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}.w\t$opt", (t2ISB instsyncb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}.w", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;

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

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

0 comments on commit 295cdd5

Please sign in to comment.