mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-11 23:16:20 +00:00
AVX-512: Add assembly parser support for Rounding mode
By Asaf Badouh <asaf.badouh@intel.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230962 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c5a15087c2
commit
53fb369429
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user