AVX-512: Add assembly parser support for Rounding mode
authorElena Demikhovsky <elena.demikhovsky@intel.com>
Mon, 2 Mar 2015 15:00:34 +0000 (15:00 +0000)
committerElena Demikhovsky <elena.demikhovsky@intel.com>
Mon, 2 Mar 2015 15:00:34 +0000 (15:00 +0000)
By Asaf Badouh <asaf.badouh@intel.com>

llvm-svn: 230962

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
llvm/lib/Target/X86/AsmParser/X86Operand.h
llvm/lib/Target/X86/X86InstrInfo.td
llvm/test/MC/X86/intel-syntax-avx512.s
llvm/test/MC/X86/x86-64-avx512f_vl.s

index 0b6fb52..c24805a 100644 (file)
@@ -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");
+  }
   }
 }
 
index d67e119..94dbedb 100644 (file)
@@ -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());
index 7ab8822..13bfe2d 100644 (file)
@@ -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
index b382994..af4e98c 100644 (file)
@@ -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}
+
index ad121dc..fd6df72 100644 (file)
 // 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
+