[llvm] r284479 - [x86][inline-asm][avx512] allow swapping of '{k<num>}' & '{z}' marks
Michael Zuckerman via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 18 06:52:40 PDT 2016
Author: mzuckerm
Date: Tue Oct 18 08:52:39 2016
New Revision: 284479
URL: http://llvm.org/viewvc/llvm-project?rev=284479&view=rev
Log:
[x86][inline-asm][avx512] allow swapping of '{k<num>}' & '{z}' marks
Committing on behalf of Coby Tayree: After check-all and LGTM
Desc:
AVX512 allows dest operand to be followed by an op-mask register specifier ('{k<num>}', which in turn may be followed by a merging/zeroing specifier ('{z}')
Currently, the following forms are allowed:
{k<num>}
{k<num>}{z}
This patch allows the following forms:
{z}{k<num>}
and ignores the next form:
{z}
Justification would be quite simple - GCC
Differential Revision: http://reviews.llvm.org/D25013
Modified:
llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
llvm/trunk/test/MC/X86/avx512bw-encoding.s
llvm/trunk/test/MC/X86/intel-syntax-avx512.s
Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=284479&r1=284478&r2=284479&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue Oct 18 08:52:39 2016
@@ -759,10 +759,12 @@ private:
/// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
/// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
- /// \return \c true if no parsing errors occurred, \c false otherwise.
+ /// return false if no parsing errors occurred, true otherwise.
bool HandleAVX512Operand(OperandVector &Operands,
const MCParsedAsmOperand &Op);
+ bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
+
bool is64BitMode() const {
// FIXME: Can tablegen auto-generate this?
return getSTI().getFeatureBits()[X86::Mode64Bit];
@@ -1907,6 +1909,28 @@ std::unique_ptr<X86Operand> X86AsmParser
}
}
+// true on failure, false otherwise
+// If no {z} mark was found - Parser doesn't advance
+bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
+ const SMLoc &StartLoc) {
+ MCAsmParser &Parser = getParser();
+ // Assuming we are just pass the '{' mark, quering the next token
+ // Searched for {z}, but none was found. Return true, as no parsing error was
+ // encountered
+ if (!(getLexer().is(AsmToken::Identifier) &&
+ (getLexer().getTok().getIdentifier() == "z")))
+ return false;
+ Parser.Lex(); // Eat z
+ // Query and eat the '}' mark
+ if (!getLexer().is(AsmToken::RCurly))
+ return Error(getLexer().getLoc(), "Expected } at this point");
+ Parser.Lex(); // Eat '}'
+ // Assign Z with the {z} mark opernad
+ Z.reset(X86Operand::CreateToken("{z}", StartLoc).release());
+ return false;
+}
+
+// true on failure, false otherwise
bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
const MCParsedAsmOperand &Op) {
MCAsmParser &Parser = getParser();
@@ -1918,11 +1942,11 @@ bool X86AsmParser::HandleAVX512Operand(O
if(getLexer().is(AsmToken::Integer)) {
// Parse memory broadcasting ({1to<NUM>}).
if (getLexer().getTok().getIntVal() != 1)
- return !TokError("Expected 1to<NUM> at this point");
+ return TokError("Expected 1to<NUM> at this point");
Parser.Lex(); // Eat "1" of 1to8
if (!getLexer().is(AsmToken::Identifier) ||
!getLexer().getTok().getIdentifier().startswith("to"))
- return !TokError("Expected 1to<NUM> at this point");
+ return TokError("Expected 1to<NUM> at this point");
// Recognize only reasonable suffixes.
const char *BroadcastPrimitive =
StringSwitch<const char*>(getLexer().getTok().getIdentifier())
@@ -1932,41 +1956,57 @@ bool X86AsmParser::HandleAVX512Operand(O
.Case("to16", "{1to16}")
.Default(nullptr);
if (!BroadcastPrimitive)
- return !TokError("Invalid memory broadcast primitive.");
+ return TokError("Invalid memory broadcast primitive.");
Parser.Lex(); // Eat "toN" of 1toN
if (!getLexer().is(AsmToken::RCurly))
- return !TokError("Expected } at this point");
+ return TokError("Expected } at this point");
Parser.Lex(); // Eat "}"
Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
consumedToken));
// No AVX512 specific primitives can pass
// after memory broadcasting, so return.
- return true;
+ return false;
} else {
- // Parse mask register {%k1}
- Operands.push_back(X86Operand::CreateToken("{", consumedToken));
- if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
- Operands.push_back(std::move(Op));
- if (!getLexer().is(AsmToken::RCurly))
- return !TokError("Expected } at this point");
- Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
-
- // Parse "zeroing non-masked" semantic {z}
- if (getLexer().is(AsmToken::LCurly)) {
- Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
- if (!getLexer().is(AsmToken::Identifier) ||
- getLexer().getTok().getIdentifier() != "z")
- return !TokError("Expected z at this point");
- Parser.Lex(); // Eat the z
+ // Parse either {k}{z}, {z}{k}, {k} or {z}
+ // last one have no meaning, but GCC accepts it
+ // Currently, we're just pass a '{' mark
+ std::unique_ptr<X86Operand> Z;
+ if (ParseZ(Z, consumedToken))
+ return true;
+ // Reaching here means that parsing of the allegadly '{z}' mark yielded
+ // no errors.
+ // Query for the need of further parsing for a {%k<NUM>} mark
+ if (!Z || getLexer().is(AsmToken::LCurly)) {
+ const SMLoc StartLoc = Z ? consumeToken() : consumedToken;
+ // Parse an op-mask register mark ({%k<NUM>}), which is now to be
+ // expected
+ if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
if (!getLexer().is(AsmToken::RCurly))
- return !TokError("Expected } at this point");
- Parser.Lex(); // Eat the }
+ return Error(getLexer().getLoc(), "Expected } at this point");
+ Operands.push_back(X86Operand::CreateToken("{", StartLoc));
+ Operands.push_back(std::move(Op));
+ Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
+ } else
+ return Error(getLexer().getLoc(),
+ "Expected an op-mask register at this point");
+ // {%k<NUM>} mark is found, inquire for {z}
+ if (getLexer().is(AsmToken::LCurly) && !Z) {
+ // Have we've found a parsing error, or found no (expected) {z} mark
+ // - report an error
+ if (ParseZ(Z, consumeToken()) || !Z)
+ return true;
+
}
+ // '{z}' on its own is meaningless, hence should be ignored.
+ // on the contrary - have it been accompanied by a K register,
+ // allow it.
+ if (Z)
+ Operands.push_back(std::move(Z));
}
}
}
}
- return true;
+ return false;
}
/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
@@ -2323,7 +2363,7 @@ bool X86AsmParser::ParseInstruction(Pars
while(1) {
if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
Operands.push_back(std::move(Op));
- if (!HandleAVX512Operand(Operands, *Operands.back()))
+ if (HandleAVX512Operand(Operands, *Operands.back()))
return true;
} else {
return true;
Modified: llvm/trunk/test/MC/X86/avx512bw-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/avx512bw-encoding.s?rev=284479&r1=284478&r2=284479&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/avx512bw-encoding.s (original)
+++ llvm/trunk/test/MC/X86/avx512bw-encoding.s Tue Oct 18 08:52:39 2016
@@ -12,6 +12,10 @@
// CHECK: encoding: [0x62,0x82,0x6d,0xc5,0x66,0xc9]
vpblendmb %zmm25, %zmm18, %zmm17 {%k5} {z}
+// CHECK: vpblendmb %zmm25, %zmm18, %zmm17 {%k5} {z}
+// CHECK: encoding: [0x62,0x82,0x6d,0xc5,0x66,0xc9]
+ vpblendmb %zmm25, %zmm18, %zmm17 {z} {%k5}
+
// CHECK: vpblendmb (%rcx), %zmm18, %zmm17
// CHECK: encoding: [0x62,0xe2,0x6d,0x40,0x66,0x09]
vpblendmb (%rcx), %zmm18, %zmm17
Modified: llvm/trunk/test/MC/X86/intel-syntax-avx512.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/intel-syntax-avx512.s?rev=284479&r1=284478&r2=284479&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/intel-syntax-avx512.s (original)
+++ llvm/trunk/test/MC/X86/intel-syntax-avx512.s Tue Oct 18 08:52:39 2016
@@ -16,6 +16,10 @@ vaddpd zmm1 {k5}, zmm1, zmm2
// CHECK: encoding: [0x62,0xf1,0xf5,0xcd,0x58,0xca]
vaddpd zmm1 {k5} {z}, zmm1, zmm2
+// CHECK: vaddpd zmm1 {k5} {z}, zmm1, zmm2
+// CHECK: encoding: [0x62,0xf1,0xf5,0xcd,0x58,0xca]
+vaddpd zmm1 {z} {k5}, zmm1, zmm2
+
// CHECK: vaddpd zmm1, zmm1, zmm2, {rn-sae}
// CHECK: encoding: [0x62,0xf1,0xf5,0x18,0x58,0xca]
vaddpd zmm1, zmm1, zmm2, {rn-sae}
More information about the llvm-commits
mailing list