Skip to content

Commit bcc1aba

Browse files
Anirudh Prasadredstar
Anirudh Prasad
authored andcommitted
[SystemZ] Introducing assembler dialects for the Z backend
- This patch introduces a different assembler dialect ("hlasm") for z/OS. The default dialect has now been given the "att" dialect name. For this appropriate changes have been added to SystemZ.td. - This patch also makes a few changes to SystemZInstrFormats.td which restrict a few condition code mnemonics to just the "att" dialect variant (he, le, lh, nhe, nle, nlh). These extended condition code mnemonics are not available in HLASM. - A new private function has been introduced in SystemZAsmParser.cpp to return the assembler dialect set in SystemZMCAsmInfo.cpp. The reason we couldn't/haven't explicitly queried the overriden getAssemblerDialect function from AsmParser is outlined in this thread here. This returned dialect is directly passed onto the relevant matcher functions which taken in a variantID, so that the matcher functions can appropriately choose an instruction based on the variant. Reviewed By: uweigand Differential Revision: https://reviews.llvm.org/D94250
1 parent 6de6455 commit bcc1aba

File tree

4 files changed

+89
-20
lines changed

4 files changed

+89
-20
lines changed

llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp

+28-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "llvm/ADT/STLExtras.h"
1313
#include "llvm/ADT/SmallVector.h"
1414
#include "llvm/ADT/StringRef.h"
15+
#include "llvm/MC/MCAsmInfo.h"
1516
#include "llvm/MC/MCContext.h"
1617
#include "llvm/MC/MCExpr.h"
1718
#include "llvm/MC/MCInst.h"
@@ -428,6 +429,27 @@ class SystemZAsmParser : public MCTargetAsmParser {
428429

429430
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
430431

432+
// Both the hlasm and att variants still rely on the basic gnu asm
433+
// format with respect to inputs, clobbers, outputs etc.
434+
//
435+
// However, calling the overriden getAssemblerDialect() method in
436+
// AsmParser is problematic. It either returns the AssemblerDialect field
437+
// in the MCAsmInfo instance if the AssemblerDialect field in AsmParser is
438+
// unset, otherwise it returns the private AssemblerDialect field in
439+
// AsmParser.
440+
//
441+
// The problematic part is because, we forcibly set the inline asm dialect
442+
// in the AsmParser instance in AsmPrinterInlineAsm.cpp. Soo any query
443+
// to the overriden getAssemblerDialect function in AsmParser.cpp, will
444+
// not return the assembler dialect set in the respective MCAsmInfo instance.
445+
//
446+
// For this purpose, we explicitly query the SystemZMCAsmInfo instance
447+
// here, to get the "correct" assembler dialect, and use it in various
448+
// functions.
449+
unsigned getMAIAssemblerDialect() {
450+
return Parser.getContext().getAsmInfo()->getAssemblerDialect();
451+
}
452+
431453
public:
432454
SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
433455
const MCInstrInfo &MII,
@@ -1325,7 +1347,7 @@ bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
13251347

13261348
// Apply mnemonic aliases first, before doing anything else, in
13271349
// case the target uses it.
1328-
applyMnemonicAliases(Name, getAvailableFeatures(), 0 /*VariantID*/);
1350+
applyMnemonicAliases(Name, getAvailableFeatures(), getMAIAssemblerDialect());
13291351

13301352
Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
13311353

@@ -1428,9 +1450,11 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
14281450
MCInst Inst;
14291451
unsigned MatchResult;
14301452

1453+
unsigned Dialect = getMAIAssemblerDialect();
1454+
14311455
FeatureBitset MissingFeatures;
1432-
MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
1433-
MissingFeatures, MatchingInlineAsm);
1456+
MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1457+
MatchingInlineAsm, Dialect);
14341458
switch (MatchResult) {
14351459
case Match_Success:
14361460
Inst.setLoc(IDLoc);
@@ -1467,7 +1491,7 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
14671491
case Match_MnemonicFail: {
14681492
FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
14691493
std::string Suggestion = SystemZMnemonicSpellCheck(
1470-
((SystemZOperand &)*Operands[0]).getToken(), FBS);
1494+
((SystemZOperand &)*Operands[0]).getToken(), FBS, Dialect);
14711495
return Error(IDLoc, "invalid instruction" + Suggestion,
14721496
((SystemZOperand &)*Operands[0]).getLocRange());
14731497
}

llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212

1313
using namespace llvm;
1414

15+
enum AsmDialect { AD_ATT = 0, AD_HLASM = 1 };
16+
1517
SystemZMCAsmInfo::SystemZMCAsmInfo(const Triple &TT) {
1618
CodePointerSize = 8;
1719
CalleeSaveStackSlotSize = 8;
1820
IsLittleEndian = false;
1921

22+
AssemblerDialect = TT.isOSzOS() ? AD_HLASM : AD_ATT;
23+
2024
MaxInstLength = 6;
2125

2226
CommentString = "#";

llvm/lib/Target/SystemZ/SystemZ.td

+15
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,27 @@ def SystemZAsmParser : AsmParser {
6767
let ShouldEmitMatchRegisterName = 0;
6868
}
6969

70+
def ATTAsmParserVariant : AsmParserVariant {
71+
int Variant = 0;
72+
73+
// Variant name.
74+
string Name = "att";
75+
}
76+
77+
def HLASMAsmParserVariant : AsmParserVariant {
78+
int Variant = 1;
79+
80+
// Variant name.
81+
string Name = "hlasm";
82+
}
83+
7084
//===----------------------------------------------------------------------===//
7185
// Top-level target declaration
7286
//===----------------------------------------------------------------------===//
7387

7488
def SystemZ : Target {
7589
let InstructionSet = SystemZInstrInfo;
7690
let AssemblyParsers = [SystemZAsmParser];
91+
let AssemblyParserVariants = [ATTAsmParserVariant, HLASMAsmParserVariant];
7792
let AllowRegisterRenaming = 1;
7893
}

llvm/lib/Target/SystemZ/SystemZInstrFormats.td

+42-16
Original file line numberDiff line numberDiff line change
@@ -1845,7 +1845,8 @@ class DirectiveInsnVSI<dag outs, dag ins, string asmstr, list<dag> pattern>
18451845
//===----------------------------------------------------------------------===//
18461846

18471847
// A class to describe a variant of an instruction with condition mask.
1848-
class CondVariant<bits<4> ccmaskin, string suffixin, bit alternatein> {
1848+
class CondVariant<bits<4> ccmaskin, string suffixin, bit alternatein,
1849+
string asmvariantin = ""> {
18491850
// The fixed condition mask to use.
18501851
bits<4> ccmask = ccmaskin;
18511852

@@ -1854,6 +1855,11 @@ class CondVariant<bits<4> ccmaskin, string suffixin, bit alternatein> {
18541855

18551856
// Whether this is an alternate that needs to be marked isAsmParserOnly.
18561857
bit alternate = alternatein;
1858+
1859+
// Whether this needs be to restricted to a specific dialect.
1860+
// Valid values are "att" and "hlasm", which when passed in
1861+
// will set AsmVariantName.
1862+
string asmvariant = asmvariantin;
18571863
}
18581864

18591865
// Condition mask 15 means "always true", which is used to define
@@ -1864,20 +1870,20 @@ def CondAlways : CondVariant<15, "", 0>;
18641870
def CondVariantO : CondVariant<1, "o", 0>;
18651871
def CondVariantH : CondVariant<2, "h", 0>;
18661872
def CondVariantP : CondVariant<2, "p", 1>;
1867-
def CondVariantNLE : CondVariant<3, "nle", 0>;
1873+
def CondVariantNLE : CondVariant<3, "nle", 0, "att">;
18681874
def CondVariantL : CondVariant<4, "l", 0>;
18691875
def CondVariantM : CondVariant<4, "m", 1>;
1870-
def CondVariantNHE : CondVariant<5, "nhe", 0>;
1871-
def CondVariantLH : CondVariant<6, "lh", 0>;
1876+
def CondVariantNHE : CondVariant<5, "nhe", 0, "att">;
1877+
def CondVariantLH : CondVariant<6, "lh", 0, "att">;
18721878
def CondVariantNE : CondVariant<7, "ne", 0>;
18731879
def CondVariantNZ : CondVariant<7, "nz", 1>;
18741880
def CondVariantE : CondVariant<8, "e", 0>;
18751881
def CondVariantZ : CondVariant<8, "z", 1>;
1876-
def CondVariantNLH : CondVariant<9, "nlh", 0>;
1877-
def CondVariantHE : CondVariant<10, "he", 0>;
1882+
def CondVariantNLH : CondVariant<9, "nlh", 0, "att">;
1883+
def CondVariantHE : CondVariant<10, "he", 0, "att">;
18781884
def CondVariantNL : CondVariant<11, "nl", 0>;
18791885
def CondVariantNM : CondVariant<11, "nm", 1>;
1880-
def CondVariantLE : CondVariant<12, "le", 0>;
1886+
def CondVariantLE : CondVariant<12, "le", 0, "att">;
18811887
def CondVariantNH : CondVariant<13, "nh", 0>;
18821888
def CondVariantNP : CondVariant<13, "np", 1>;
18831889
def CondVariantNO : CondVariant<14, "no", 0>;
@@ -1886,35 +1892,38 @@ def CondVariantNO : CondVariant<14, "no", 0>;
18861892
class CV<string name>
18871893
: CondVariant<!cast<CondVariant>("CondVariant"#name).ccmask,
18881894
!cast<CondVariant>("CondVariant"#name).suffix,
1889-
!cast<CondVariant>("CondVariant"#name).alternate>;
1895+
!cast<CondVariant>("CondVariant"#name).alternate,
1896+
!cast<CondVariant>("CondVariant"#name).asmvariant>;
18901897

18911898
// Condition masks for integer instructions (e.g. compare-and-branch).
18921899
// This is like the list above, except that condition 3 is not possible
18931900
// and that the low bit of the mask is therefore always 0. This means
18941901
// that each condition has two names. Conditions "o" and "no" are not used.
18951902
def IntCondVariantH : CondVariant<2, "h", 0>;
1896-
def IntCondVariantNLE : CondVariant<2, "nle", 1>;
1903+
def IntCondVariantNLE : CondVariant<2, "nle", 1, "att">;
18971904
def IntCondVariantL : CondVariant<4, "l", 0>;
1898-
def IntCondVariantNHE : CondVariant<4, "nhe", 1>;
1899-
def IntCondVariantLH : CondVariant<6, "lh", 0>;
1905+
def IntCondVariantNHE : CondVariant<4, "nhe", 1, "att">;
1906+
def IntCondVariantLH : CondVariant<6, "lh", 0, "att">;
19001907
def IntCondVariantNE : CondVariant<6, "ne", 1>;
19011908
def IntCondVariantE : CondVariant<8, "e", 0>;
1902-
def IntCondVariantNLH : CondVariant<8, "nlh", 1>;
1903-
def IntCondVariantHE : CondVariant<10, "he", 0>;
1909+
def IntCondVariantNLH : CondVariant<8, "nlh", 1, "att">;
1910+
def IntCondVariantHE : CondVariant<10, "he", 0, "att">;
19041911
def IntCondVariantNL : CondVariant<10, "nl", 1>;
1905-
def IntCondVariantLE : CondVariant<12, "le", 0>;
1912+
def IntCondVariantLE : CondVariant<12, "le", 0, "att">;
19061913
def IntCondVariantNH : CondVariant<12, "nh", 1>;
19071914

19081915
// A helper class to look up one of the above by name.
19091916
class ICV<string name>
19101917
: CondVariant<!cast<CondVariant>("IntCondVariant"#name).ccmask,
19111918
!cast<CondVariant>("IntCondVariant"#name).suffix,
1912-
!cast<CondVariant>("IntCondVariant"#name).alternate>;
1919+
!cast<CondVariant>("IntCondVariant"#name).alternate,
1920+
!cast<CondVariant>("IntCondVariant"#name).asmvariant>;
19131921

19141922
// Defines a class that makes it easier to define
19151923
// a MnemonicAlias when CondVariant's are involved.
19161924
class MnemonicCondBranchAlias<CondVariant V, string from, string to>
1917-
: MnemonicAlias<!subst("#", V.suffix, from), !subst("#", V.suffix, to)>;
1925+
: MnemonicAlias<!subst("#", V.suffix, from), !subst("#", V.suffix, to),
1926+
V.asmvariant>;
19181927

19191928
//===----------------------------------------------------------------------===//
19201929
// Instruction definitions with semantics
@@ -2125,6 +2134,7 @@ class FixedCondBranchRI<CondVariant V, string mnemonic, bits<12> opcode,
21252134
: InstRIc<opcode, (outs), (ins brtarget16:$RI2),
21262135
!subst("#", V.suffix, mnemonic)#"\t$RI2", [(operator bb:$RI2)]> {
21272136
let isAsmParserOnly = V.alternate;
2137+
let AsmVariantName = V.asmvariant;
21282138
let M1 = V.ccmask;
21292139
}
21302140

@@ -2142,6 +2152,7 @@ class FixedCondBranchRIL<CondVariant V, string mnemonic, bits<12> opcode>
21422152
: InstRILc<opcode, (outs), (ins brtarget32:$RI2),
21432153
!subst("#", V.suffix, mnemonic)#"\t$RI2", []> {
21442154
let isAsmParserOnly = V.alternate;
2155+
let AsmVariantName = V.asmvariant;
21452156
let M1 = V.ccmask;
21462157
}
21472158

@@ -2160,6 +2171,7 @@ class FixedCondBranchRR<CondVariant V, string mnemonic, bits<8> opcode,
21602171
: InstRR<opcode, (outs), (ins ADDR64:$R2),
21612172
!subst("#", V.suffix, mnemonic)#"\t$R2", [(operator ADDR64:$R2)]> {
21622173
let isAsmParserOnly = V.alternate;
2174+
let AsmVariantName = V.asmvariant;
21632175
let R1 = V.ccmask;
21642176
}
21652177

@@ -2177,6 +2189,7 @@ class FixedCondBranchRX<CondVariant V, string mnemonic, bits<8> opcode>
21772189
: InstRXb<opcode, (outs), (ins bdxaddr12only:$XBD2),
21782190
!subst("#", V.suffix, mnemonic)#"\t$XBD2", []> {
21792191
let isAsmParserOnly = V.alternate;
2192+
let AsmVariantName = V.asmvariant;
21802193
let M1 = V.ccmask;
21812194
}
21822195

@@ -2199,6 +2212,7 @@ class FixedCondBranchRXY<CondVariant V, string mnemonic, bits<16> opcode,
21992212
!subst("#", V.suffix, mnemonic)#"\t$XBD2",
22002213
[(operator (load bdxaddr20only:$XBD2))]> {
22012214
let isAsmParserOnly = V.alternate;
2215+
let AsmVariantName = V.asmvariant;
22022216
let M1 = V.ccmask;
22032217
let mayLoad = 1;
22042218
}
@@ -2218,6 +2232,7 @@ class FixedCmpBranchRIEa<CondVariant V, string mnemonic, bits<16> opcode,
22182232
: InstRIEa<opcode, (outs), (ins cls:$R1, imm:$I2),
22192233
mnemonic#V.suffix#"\t$R1, $I2", []> {
22202234
let isAsmParserOnly = V.alternate;
2235+
let AsmVariantName = V.asmvariant;
22212236
let M3 = V.ccmask;
22222237
}
22232238

@@ -2245,6 +2260,7 @@ class FixedCmpBranchRIEb<CondVariant V, string mnemonic, bits<16> opcode,
22452260
: InstRIEb<opcode, (outs), (ins cls:$R1, cls:$R2, brtarget16:$RI4),
22462261
mnemonic#V.suffix#"\t$R1, $R2, $RI4", []> {
22472262
let isAsmParserOnly = V.alternate;
2263+
let AsmVariantName = V.asmvariant;
22482264
let M3 = V.ccmask;
22492265
}
22502266

@@ -2272,6 +2288,7 @@ class FixedCmpBranchRIEc<CondVariant V, string mnemonic, bits<16> opcode,
22722288
: InstRIEc<opcode, (outs), (ins cls:$R1, imm:$I2, brtarget16:$RI4),
22732289
mnemonic#V.suffix#"\t$R1, $I2, $RI4", []> {
22742290
let isAsmParserOnly = V.alternate;
2291+
let AsmVariantName = V.asmvariant;
22752292
let M3 = V.ccmask;
22762293
}
22772294

@@ -2304,6 +2321,7 @@ class FixedCmpBranchRRFc<CondVariant V, string mnemonic, bits<16> opcode,
23042321
: InstRRFc<opcode, (outs), (ins cls:$R1, cls:$R2),
23052322
mnemonic#V.suffix#"\t$R1, $R2", []> {
23062323
let isAsmParserOnly = V.alternate;
2324+
let AsmVariantName = V.asmvariant;
23072325
let M3 = V.ccmask;
23082326
}
23092327

@@ -2324,6 +2342,7 @@ class FixedCmpBranchRRS<CondVariant V, string mnemonic, bits<16> opcode,
23242342
: InstRRS<opcode, (outs), (ins cls:$R1, cls:$R2, bdaddr12only:$BD4),
23252343
mnemonic#V.suffix#"\t$R1, $R2, $BD4", []> {
23262344
let isAsmParserOnly = V.alternate;
2345+
let AsmVariantName = V.asmvariant;
23272346
let M3 = V.ccmask;
23282347
}
23292348

@@ -2351,6 +2370,7 @@ class FixedCmpBranchRIS<CondVariant V, string mnemonic, bits<16> opcode,
23512370
: InstRIS<opcode, (outs), (ins cls:$R1, imm:$I2, bdaddr12only:$BD4),
23522371
mnemonic#V.suffix#"\t$R1, $I2, $BD4", []> {
23532372
let isAsmParserOnly = V.alternate;
2373+
let AsmVariantName = V.asmvariant;
23542374
let M3 = V.ccmask;
23552375
}
23562376

@@ -2383,6 +2403,7 @@ class FixedCmpBranchRSYb<CondVariant V, string mnemonic, bits<16> opcode,
23832403
: InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2),
23842404
mnemonic#V.suffix#"\t$R1, $BD2", []> {
23852405
let isAsmParserOnly = V.alternate;
2406+
let AsmVariantName = V.asmvariant;
23862407
let M3 = V.ccmask;
23872408
}
23882409

@@ -2717,6 +2738,7 @@ class FixedCondStoreRSY<CondVariant V, string mnemonic, bits<16> opcode,
27172738
let mayStore = 1;
27182739
let AccessBytes = bytes;
27192740
let isAsmParserOnly = V.alternate;
2741+
let AsmVariantName = V.asmvariant;
27202742
let M3 = V.ccmask;
27212743
}
27222744

@@ -2891,6 +2913,7 @@ class FixedCondUnaryRSY<CondVariant V, string mnemonic, bits<16> opcode,
28912913
let mayLoad = 1;
28922914
let AccessBytes = bytes;
28932915
let isAsmParserOnly = V.alternate;
2916+
let AsmVariantName = V.asmvariant;
28942917
let M3 = V.ccmask;
28952918
}
28962919

@@ -3294,6 +3317,7 @@ class FixedCondBinaryRRF<CondVariant V, string mnemonic, bits<16> opcode,
32943317
let Constraints = "$R1 = $R1src";
32953318
let DisableEncoding = "$R1src";
32963319
let isAsmParserOnly = V.alternate;
3320+
let AsmVariantName = V.asmvariant;
32973321
let M3 = V.ccmask;
32983322
}
32993323

@@ -3332,6 +3356,7 @@ class FixedCondBinaryRRFa<CondVariant V, string mnemonic, bits<16> opcode,
33323356
: InstRRFa<opcode, (outs cls1:$R1), (ins cls3:$R3, cls2:$R2),
33333357
mnemonic#V.suffix#"\t$R1, $R2, $R3", []> {
33343358
let isAsmParserOnly = V.alternate;
3359+
let AsmVariantName = V.asmvariant;
33353360
let M4 = V.ccmask;
33363361
}
33373362

@@ -3401,6 +3426,7 @@ class FixedCondBinaryRIE<CondVariant V, string mnemonic, bits<16> opcode,
34013426
let Constraints = "$R1 = $R1src";
34023427
let DisableEncoding = "$R1src";
34033428
let isAsmParserOnly = V.alternate;
3429+
let AsmVariantName = V.asmvariant;
34043430
let M3 = V.ccmask;
34053431
}
34063432

0 commit comments

Comments
 (0)