llvm.org GIT mirror llvm / 08316a1
AVX-512: Assembly parsing of broadcast semantic in AVX-512; imlemented by Nis Zinovy (zinovy.y.nis@intel.com) Fixed truncate i32 to i1; a test will be provided in the next commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201757 91177308-0d34-0410-b5e6-96231b3b80d8 Elena Demikhovsky 6 years ago
3 changed file(s) with 118 addition(s) and 69 deletion(s). Raw diff Collapse all Expand all
604604 return Parser.Error(L, Msg, Ranges);
605605 }
606606
607 bool ErrorAndEatStatement(SMLoc L, const Twine &Msg,
608 ArrayRef Ranges = None,
609 bool MatchingInlineAsm = false) {
610 Parser.eatToEndOfStatement();
611 return Error(L, Msg, Ranges, MatchingInlineAsm);
612 }
613
607614 X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) {
608615 Error(Loc, Msg);
609616 return 0;
650657 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
651658 /// the parsing mode (Intel vs. AT&T).
652659 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
660
661 /// Parses AVX512 specific operand primitives: masked registers ({%k}, {z})
662 /// and memory broadcasting ({1to}) primitives, updating Operands vector if required.
663 /// \return \c true if no parsing errors occurred, \c false otherwise.
664 bool HandleAVX512Operand(SmallVectorImpl &Operands,
665 const MCParsedAsmOperand &Op);
653666
654667 bool is64BitMode() const {
655668 // FIXME: Can tablegen auto-generate this?
20242037 return X86Operand::CreateImm(Val, Start, End);
20252038 }
20262039 }
2040 }
2041
2042 bool X86AsmParser::HandleAVX512Operand(SmallVectorImpl &Operands,
2043 const MCParsedAsmOperand &Op) {
2044 if(STI.getFeatureBits() & X86::FeatureAVX512) {
2045 if (getLexer().is(AsmToken::LCurly)) {
2046 // Eat "{" and mark the current place.
2047 const SMLoc consumedToken = consumeToken();
2048 // Distinguish {1to} from {%k}.
2049 if(getLexer().is(AsmToken::Integer)) {
2050 // Parse memory broadcasting ({1to}).
2051 if (getLexer().getTok().getIntVal() != 1)
2052 return !ErrorAndEatStatement(getLexer().getLoc(),
2053 "Expected 1to at this point");
2054 Parser.Lex(); // Eat "1" of 1to8
2055 if (!getLexer().is(AsmToken::Identifier) ||
2056 !getLexer().getTok().getIdentifier().startswith("to"))
2057 return !ErrorAndEatStatement(getLexer().getLoc(),
2058 "Expected 1to at this point");
2059 // Recognize only reasonable suffixes.
2060 const char *BroadcastPrimitive =
2061 StringSwitch(getLexer().getTok().getIdentifier())
2062 .Case("to8", "{1to8}")
2063 .Case("to16", "{1to16}")
2064 .Default(0);
2065 if (!BroadcastPrimitive)
2066 return !ErrorAndEatStatement(getLexer().getLoc(),
2067 "Invalid memory broadcast primitive.");
2068 Parser.Lex(); // Eat "toN" of 1toN
2069 if (!getLexer().is(AsmToken::RCurly))
2070 return !ErrorAndEatStatement(getLexer().getLoc(),
2071 "Expected } at this point");
2072 Parser.Lex(); // Eat "}"
2073 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
2074 consumedToken));
2075 // No AVX512 specific primitives can pass
2076 // after memory broadcasting, so return.
2077 return true;
2078 } else {
2079 // Parse mask register {%k1}
2080 Operands.push_back(X86Operand::CreateToken("{", consumedToken));
2081 if (X86Operand *Op = ParseOperand()) {
2082 Operands.push_back(Op);
2083 if (!getLexer().is(AsmToken::RCurly))
2084 return !ErrorAndEatStatement(getLexer().getLoc(),
2085 "Expected } at this point");
2086 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
2087
2088 // Parse "zeroing non-masked" semantic {z}
2089 if (getLexer().is(AsmToken::LCurly)) {
2090 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
2091 if (!getLexer().is(AsmToken::Identifier) ||
2092 getLexer().getTok().getIdentifier() != "z")
2093 return !ErrorAndEatStatement(getLexer().getLoc(),
2094 "Expected z at this point");
2095 Parser.Lex(); // Eat the z
2096 if (!getLexer().is(AsmToken::RCurly))
2097 return !ErrorAndEatStatement(getLexer().getLoc(),
2098 "Expected } at this point");
2099 Parser.Lex(); // Eat the }
2100 }
2101 }
2102 }
2103 }
2104 }
2105 return true;
20272106 }
20282107
20292108 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
22842363 if (getLexer().is(AsmToken::Star))
22852364 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
22862365
2287 // Read the first operand.
2288 if (X86Operand *Op = ParseOperand())
2289 Operands.push_back(Op);
2290 else {
2291 Parser.eatToEndOfStatement();
2292 return true;
2293 }
2294
2295 while (getLexer().is(AsmToken::Comma)) {
2296 Parser.Lex(); // Eat the comma.
2297
2298 // Parse and remember the operand.
2299 if (X86Operand *Op = ParseOperand())
2300 Operands.push_back(Op);
2301 else {
2302 Parser.eatToEndOfStatement();
2303 return true;
2304 }
2305 }
2306
2307 if (STI.getFeatureBits() & X86::FeatureAVX512) {
2308 // Parse mask register {%k1}
2309 if (getLexer().is(AsmToken::LCurly)) {
2310 Operands.push_back(X86Operand::CreateToken("{", consumeToken()));
2311 if (X86Operand *Op = ParseOperand()) {
2312 Operands.push_back(Op);
2313 if (!getLexer().is(AsmToken::RCurly)) {
2314 SMLoc Loc = getLexer().getLoc();
2315 Parser.eatToEndOfStatement();
2316 return Error(Loc, "Expected } at this point");
2317 }
2318 Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
2319 } else {
2320 Parser.eatToEndOfStatement();
2366 // Read the operands.
2367 while(1) {
2368 if (X86Operand *Op = ParseOperand()) {
2369 Operands.push_back(Op);
2370 if (!HandleAVX512Operand(Operands, *Op))
23212371 return true;
2322 }
2323 }
2324 // TODO: add parsing of broadcasts {1to8}, {1to16}
2325 // Parse "zeroing non-masked" semantic {z}
2326 if (getLexer().is(AsmToken::LCurly)) {
2327 Operands.push_back(X86Operand::CreateToken("{z}", consumeToken()));
2328 if (!getLexer().is(AsmToken::Identifier) || getLexer().getTok().getIdentifier() != "z") {
2329 SMLoc Loc = getLexer().getLoc();
2330 Parser.eatToEndOfStatement();
2331 return Error(Loc, "Expected z at this point");
2332 }
2333 Parser.Lex(); // Eat the z
2334 if (!getLexer().is(AsmToken::RCurly)) {
2335 SMLoc Loc = getLexer().getLoc();
2336 Parser.eatToEndOfStatement();
2337 return Error(Loc, "Expected } at this point");
2338 }
2339 Parser.Lex(); // Eat the }
2340 }
2341 }
2342
2343 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2344 SMLoc Loc = getLexer().getLoc();
2345 Parser.eatToEndOfStatement();
2346 return Error(Loc, "unexpected token in argument list");
2347 }
2348 }
2349
2350 if (getLexer().is(AsmToken::EndOfStatement))
2351 Parser.Lex(); // Consume the EndOfStatement
2352 else if (isPrefix && getLexer().is(AsmToken::Slash))
2353 Parser.Lex(); // Consume the prefix separator Slash
2372 } else {
2373 Parser.eatToEndOfStatement();
2374 return true;
2375 }
2376 // check for comma and eat it
2377 if (getLexer().is(AsmToken::Comma))
2378 Parser.Lex();
2379 else
2380 break;
2381 }
2382
2383 if (getLexer().isNot(AsmToken::EndOfStatement))
2384 return ErrorAndEatStatement(getLexer().getLoc(), "unexpected token in argument list");
2385 }
2386
2387 // Consume the EndOfStatement or the prefix separator Slash
2388 if (getLexer().is(AsmToken::EndOfStatement) || isPrefix && getLexer().is(AsmToken::Slash))
2389 Parser.Lex();
23542390
23552391 if (ExtraImmOp && isParsingIntelSyntax())
23562392 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
955955 (COPY_TO_REGCLASS (KMOVWkm addr:$src), VK8)>;
956956
957957 def : Pat<(i1 (trunc (i32 GR32:$src))),
958 (COPY_TO_REGCLASS (KMOVWkr $src), VK1)>;
958 (COPY_TO_REGCLASS (KMOVWkr (AND32ri $src, (i32 1))), VK1)>;
959959
960960 def : Pat<(i1 (trunc (i8 GR8:$src))),
961 (COPY_TO_REGCLASS
962 (KMOVWkr (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)), VK1)>;
961 (COPY_TO_REGCLASS
962 (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit), (i32 1))),
963 VK1)>;
964 def : Pat<(i1 (trunc (i16 GR16:$src))),
965 (COPY_TO_REGCLASS
966 (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), $src, sub_16bit), (i32 1))),
967 VK1)>;
963968
964969 def : Pat<(i32 (zext VK1:$src)), (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16))>;
965970 def : Pat<(i8 (zext VK1:$src)),
5050 // CHECK: vextractps
5151 // CHECK: encoding: [0x62,0xe3,0x7d,0x08,0x17,0x61,0x1f,0x02]
5252 vextractps $2, %xmm20, 124(%rcx)
53
54 // CHECK: vaddpd {{.*}}{1to8}
55 // CHECK: encoding: [0x62,0x61,0xdd,0x50,0x58,0x74,0xf7,0x40]
56 vaddpd 512(%rdi, %rsi, 8) {1to8}, %zmm20, %zmm30
57
58 // CHECK: vaddps {{.*}}{1to16}
59 // CHECK: encoding: [0x62,0x61,0x5c,0x50,0x58,0xb4,0xf7,0x00,0x02,0x00,0x00]
60 vaddps 512(%rdi, %rsi, 8) {1to16}, %zmm20, %zmm30