diff options
author | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2015-03-02 15:00:34 +0000 |
---|---|---|
committer | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2015-03-02 15:00:34 +0000 |
commit | 18fd49602b4e5c1c141a19f031b9f6d5caa7a423 (patch) | |
tree | 7f3849b5c9e1384165f106ae5ede6bb705d0cba1 /llvm | |
parent | 45ddd694fdcd2bdeeb2599934f1cc0e69e5db27a (diff) | |
download | llvm-18fd49602b4e5c1c141a19f031b9f6d5caa7a423.zip llvm-18fd49602b4e5c1c141a19f031b9f6d5caa7a423.tar.gz llvm-18fd49602b4e5c1c141a19f031b9f6d5caa7a423.tar.bz2 |
AVX-512: Add assembly parser support for Rounding mode
By Asaf Badouh <asaf.badouh@intel.com>
llvm-svn: 230962
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 42 | ||||
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86Operand.h | 8 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 5 | ||||
-rw-r--r-- | llvm/test/MC/X86/intel-syntax-avx512.s | 29 | ||||
-rw-r--r-- | llvm/test/MC/X86/x86-64-avx512f_vl.s | 33 |
5 files changed, 115 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 0b6fb52..c24805a6 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -11,6 +11,7 @@ #include "X86AsmInstrumentation.h" #include "X86AsmParserCommon.h" #include "X86Operand.h" +#include "X86ISelLowering.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" @@ -664,6 +665,7 @@ private: ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size); std::unique_ptr<X86Operand> ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size); + std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End); bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End); std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg, SMLoc Start, @@ -1407,6 +1409,35 @@ X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, /*Scale=*/1, Start, End, Size, Identifier, Info); } +//ParseRoundingModeOp - Parse AVX-512 rounding mode operand +std::unique_ptr<X86Operand> +X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) { + MCAsmParser &Parser = getParser(); + const AsmToken &Tok = Parser.getTok(); + consumeToken(); // Eat "{" + if (Tok.getIdentifier().startswith("r")){ + int rndMode = StringSwitch<int>(Tok.getIdentifier()) + .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT) + .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF) + .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF) + .Case("rz", X86::STATIC_ROUNDING::TO_ZERO) + .Default(-1); + if (-1 == rndMode) + return ErrorOperand(Tok.getLoc(), "Invalid rounding mode."); + Parser.Lex(); // Eat "r*" of r*-sae + if (!getLexer().is(AsmToken::Minus)) + return ErrorOperand(Tok.getLoc(), "Expected - at this point"); + Parser.Lex(); // Eat "-" + Parser.Lex(); // Eat the sae + if (!getLexer().is(AsmToken::RCurly)) + return ErrorOperand(Tok.getLoc(), "Expected } at this point"); + Parser.Lex(); // Eat "}" + const MCExpr *RndModeOp = + MCConstantExpr::Create(rndMode, Parser.getContext()); + return X86Operand::CreateImm(RndModeOp, Start, End); + } + return ErrorOperand(Tok.getLoc(), "unknown token in expression"); +} /// ParseIntelMemOperand - Parse intel style memory operand. std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp, SMLoc Start, @@ -1656,6 +1687,11 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() { return ParseIntelMemOperand(Imm, Start, Size); } + // rounding mode token + if (STI.getFeatureBits() & X86::FeatureAVX512 && + getLexer().is(AsmToken::LCurly)) + return ParseRoundingModeOp(Start, End); + // Register. unsigned RegNo = 0; if (!ParseRegister(RegNo, Start, End)) { @@ -1708,6 +1744,12 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() { return nullptr; return X86Operand::CreateImm(Val, Start, End); } + case AsmToken::LCurly:{ + SMLoc Start = Parser.getTok().getLoc(), End; + if (STI.getFeatureBits() & X86::FeatureAVX512) + return ParseRoundingModeOp(Start, End); + return ErrorOperand(Start, "unknown token in expression"); + } } } diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h index d67e119..94dbedb 100644 --- a/llvm/lib/Target/X86/AsmParser/X86Operand.h +++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h @@ -260,6 +260,9 @@ struct X86Operand : public MCParsedAsmOperand { return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && !getMemIndexReg() && getMemScale() == 1; } + bool isAVX512RC() const{ + return isImm(); + } bool isAbsMem16() const { return isAbsMem() && Mem.ModeSize == 16; @@ -394,7 +397,10 @@ struct X86Operand : public MCParsedAsmOperand { RegNo = getGR32FromGR64(RegNo); Inst.addOperand(MCOperand::CreateReg(RegNo)); } - + void addAVX512RCOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addExpr(Inst, getImm()); + } void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); addExpr(Inst, getImm()); diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 7ab8822..13bfe2d 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -572,10 +572,13 @@ def X86GR32orGR64AsmOperand : AsmOperandClass { def GR32orGR64 : RegisterOperand<GR32> { let ParserMatchClass = X86GR32orGR64AsmOperand; } - +def AVX512RCOperand : AsmOperandClass { + let Name = "AVX512RC"; +} def AVX512RC : Operand<i32> { let PrintMethod = "printRoundingControl"; let OperandType = "OPERAND_IMMEDIATE"; + let ParserMatchClass = AVX512RCOperand; } // Sign-extended immediate classes. We don't need to define the full lattice diff --git a/llvm/test/MC/X86/intel-syntax-avx512.s b/llvm/test/MC/X86/intel-syntax-avx512.s index b382994..af4e98c 100644 --- a/llvm/test/MC/X86/intel-syntax-avx512.s +++ b/llvm/test/MC/X86/intel-syntax-avx512.s @@ -3,3 +3,32 @@ // CHECK: vaddps (%rax), %zmm1, %zmm1 // CHECK: encoding: [0x62,0xf1,0x74,0x48,0x58,0x08] vaddps zmm1, zmm1, zmmword ptr [rax] + +// CHECK: vaddpd %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x48,0x58,0xca] +vaddpd zmm1,zmm1,zmm2 + +// CHECK: vaddpd %zmm2, %zmm1, %zmm1 {%k5} +// CHECK: encoding: [0x62,0xf1,0xf5,0x4d,0x58,0xca] +vaddpd zmm1{k5},zmm1,zmm2 + +// CHECK: vaddpd %zmm2, %zmm1, %zmm1 {%k5} {z} +// CHECK: encoding: [0x62,0xf1,0xf5,0xcd,0x58,0xca] +vaddpd zmm1{k5} {z},zmm1,zmm2 + +// CHECK: vaddpd {rn-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x18,0x58,0xca] +vaddpd zmm1,zmm1,zmm2,{rn-sae} + +// CHECK: vaddpd {ru-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x58,0x58,0xca] +vaddpd zmm1,zmm1,zmm2,{ru-sae} + +// CHECK: vaddpd {rd-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x38,0x58,0xca] +vaddpd zmm1,zmm1,zmm2,{rd-sae} + +// CHECK: vaddpd {rz-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x78,0x58,0xca] +vaddpd zmm1,zmm1,zmm2,{rz-sae} + diff --git a/llvm/test/MC/X86/x86-64-avx512f_vl.s b/llvm/test/MC/X86/x86-64-avx512f_vl.s index ad121dc..fd6df72 100644 --- a/llvm/test/MC/X86/x86-64-avx512f_vl.s +++ b/llvm/test/MC/X86/x86-64-avx512f_vl.s @@ -6651,3 +6651,36 @@ // CHECK: vmovups %ymm23, -4128(%rdx) // CHECK: encoding: [0x62,0xe1,0x7c,0x28,0x11,0xba,0xe0,0xef,0xff,0xff] vmovups %ymm23, -4128(%rdx) + +// CHECK: vaddpd %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x48,0x58,0xca] +vaddpd %zmm2, %zmm1, %zmm1 + +// CHECK: vaddpd %zmm2, %zmm1, %zmm1 {%k5} +// CHECK: encoding: [0x62,0xf1,0xf5,0x4d,0x58,0xca] +vaddpd %zmm2, %zmm1, %zmm1 {%k5} + +// CHECK: vaddpd %zmm2, %zmm1, %zmm1 {%k5} {z} +// CHECK: encoding: [0x62,0xf1,0xf5,0xcd,0x58,0xca] +vaddpd %zmm2, %zmm1, %zmm1 {%k5} {z} + +// CHECK: vaddpd {rn-sae}, %zmm2, %zmm1, %zmm1 {%k5} {z} +// CHECK: encoding: [0x62,0xf1,0xf5,0x9d,0x58,0xca] +vaddpd {rn-sae}, %zmm2, %zmm1, %zmm1 {%k5} {z} + +// CHECK: vaddpd {rn-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x18,0x58,0xca] +vaddpd {rn-sae}, %zmm2, %zmm1, %zmm1 + +// CHECK: vaddpd {ru-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x58,0x58,0xca] +vaddpd {ru-sae}, %zmm2, %zmm1, %zmm1 + +// CHECK: vaddpd {rd-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x38,0x58,0xca] +vaddpd {rd-sae}, %zmm2, %zmm1, %zmm1 + +// CHECK: vaddpd {rz-sae}, %zmm2, %zmm1, %zmm1 +// CHECK: encoding: [0x62,0xf1,0xf5,0x78,0x58,0xca] +vaddpd {rz-sae}, %zmm2, %zmm1, %zmm1 + |