[llvm] r349048 - [Sparc] Add membar assembler tags

Daniel Cederman via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 13 07:29:12 PST 2018


Author: dcederman
Date: Thu Dec 13 07:29:12 2018
New Revision: 349048

URL: http://llvm.org/viewvc/llvm-project?rev=349048&view=rev
Log:
[Sparc] Add membar assembler tags

Summary: The Sparc V9 membar instruction can enforce different types of
memory orderings depending on the value in its immediate field.  In the
architectural manual the type is selected by combining different assembler
tags into a mask. This patch adds support for these tags.

Reviewers: jyknight, venkatra, brad

Reviewed By: jyknight

Subscribers: fedor.sergeev, jrtc27, jfb, llvm-commits

Differential Revision: https://reviews.llvm.org/D53491

Modified:
    llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
    llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
    llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
    llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
    llvm/trunk/test/MC/Disassembler/Sparc/sparc-v9.txt
    llvm/trunk/test/MC/Sparc/sparc-asm-errors.s
    llvm/trunk/test/MC/Sparc/sparcv9-atomic-instructions.s

Modified: llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp?rev=349048&r1=349047&r2=349048&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp Thu Dec 13 07:29:12 2018
@@ -78,6 +78,8 @@ class SparcAsmParser : public MCTargetAs
   // Custom parse functions for Sparc specific operands.
   OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
 
+  OperandMatchResultTy parseMembarTag(OperandVector &Operands);
+
   OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
 
   OperandMatchResultTy
@@ -256,6 +258,7 @@ public:
   bool isMem() const override { return isMEMrr() || isMEMri(); }
   bool isMEMrr() const { return Kind == k_MemoryReg; }
   bool isMEMri() const { return Kind == k_MemoryImm; }
+  bool isMembarTag() const { return Kind == k_Immediate; }
 
   bool isIntReg() const {
     return (Kind == k_Register && Reg.Kind == rk_IntReg);
@@ -366,6 +369,12 @@ public:
     addExpr(Inst, Expr);
   }
 
+  void addMembarTagOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    const MCExpr *Expr = getImm();
+    addExpr(Inst, Expr);
+  }
+
   static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
     auto Op = make_unique<SparcOperand>(k_Token);
     Op->Tok.Data = Str.data();
@@ -742,6 +751,52 @@ SparcAsmParser::parseMEMOperand(OperandV
   return MatchOperand_Success;
 }
 
+OperandMatchResultTy SparcAsmParser::parseMembarTag(OperandVector &Operands) {
+  SMLoc S = Parser.getTok().getLoc();
+  const MCExpr *EVal;
+  int64_t ImmVal = 0;
+
+  std::unique_ptr<SparcOperand> Mask;
+  if (parseSparcAsmOperand(Mask) == MatchOperand_Success) {
+    if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
+        ImmVal < 0 || ImmVal > 127) {
+      Error(S, "invalid membar mask number");
+      return MatchOperand_ParseFail;
+    }
+  }
+
+  while (getLexer().getKind() == AsmToken::Hash) {
+    SMLoc TagStart = getLexer().getLoc();
+    Parser.Lex(); // Eat the '#'.
+    unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
+      .Case("LoadLoad", 0x1)
+      .Case("StoreLoad", 0x2)
+      .Case("LoadStore", 0x4)
+      .Case("StoreStore", 0x8)
+      .Case("Lookaside", 0x10)
+      .Case("MemIssue", 0x20)
+      .Case("Sync", 0x40)
+      .Default(0);
+
+    Parser.Lex(); // Eat the identifier token.
+
+    if (!MaskVal) {
+      Error(TagStart, "unknown membar tag");
+      return MatchOperand_ParseFail;
+    }
+
+    ImmVal |= MaskVal;
+
+    if (getLexer().getKind() == AsmToken::Pipe)
+      Parser.Lex(); // Eat the '|'.
+  }
+
+  EVal = MCConstantExpr::create(ImmVal, getContext());
+  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+  Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
+  return MatchOperand_Success;
+}
+
 OperandMatchResultTy
 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
 

Modified: llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp?rev=349048&r1=349047&r2=349048&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp Thu Dec 13 07:29:12 2018
@@ -195,3 +195,26 @@ bool SparcInstPrinter::printGetPCX(const
   llvm_unreachable("FIXME: Implement SparcInstPrinter::printGetPCX.");
   return true;
 }
+
+void SparcInstPrinter::printMembarTag(const MCInst *MI, int opNum,
+                                      const MCSubtargetInfo &STI,
+                                      raw_ostream &O) {
+  static const char *const TagNames[] = {
+      "#LoadLoad",  "#StoreLoad", "#LoadStore", "#StoreStore",
+      "#Lookaside", "#MemIssue",  "#Sync"};
+
+  unsigned Imm = MI->getOperand(opNum).getImm();
+
+  if (Imm > 127) {
+    O << Imm;
+    return;
+  }
+
+  bool First = true;
+  for (unsigned i = 0; i < sizeof(TagNames) / sizeof(char *); i++) {
+    if (Imm & (1 << i)) {
+      O << (First ? "" : " | ") << TagNames[i];
+      First = false;
+    }
+  }
+}

Modified: llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h?rev=349048&r1=349047&r2=349048&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h (original)
+++ llvm/trunk/lib/Target/Sparc/InstPrinter/SparcInstPrinter.h Thu Dec 13 07:29:12 2018
@@ -49,6 +49,8 @@ public:
                       raw_ostream &OS);
   bool printGetPCX(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                    raw_ostream &OS);
+  void printMembarTag(const MCInst *MI, int opNum, const MCSubtargetInfo &STI,
+                      raw_ostream &O);
 };
 } // end namespace llvm
 

Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=349048&r1=349047&r2=349048&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Thu Dec 13 07:29:12 2018
@@ -138,6 +138,16 @@ def MEMri : Operand<iPTR> {
 
 def TLSSym : Operand<iPTR>;
 
+def SparcMembarTagAsmOperand : AsmOperandClass {
+  let Name = "MembarTag";
+  let ParserMethod = "parseMembarTag";
+}
+
+def MembarTag : Operand<i32> {
+  let PrintMethod = "printMembarTag";
+  let ParserMatchClass = SparcMembarTagAsmOperand;
+}
+
 // Branch targets have OtherVT type.
 def brtarget : Operand<OtherVT> {
   let EncoderMethod = "getBranchTargetOpValue";
@@ -1503,7 +1513,7 @@ def : Pat<(ctpop i32:$src),
           (POPCrr (SRLri $src, 0))>;
 
 let Predicates = [HasV9], hasSideEffects = 1, rd = 0, rs1 = 0b01111 in
- def MEMBARi : F3_2<2, 0b101000, (outs), (ins simm13Op:$simm13),
+ def MEMBARi : F3_2<2, 0b101000, (outs), (ins MembarTag:$simm13),
                     "membar $simm13", []>;
 
 // The CAS instruction, unlike other instructions, only comes in a 

Modified: llvm/trunk/test/MC/Disassembler/Sparc/sparc-v9.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Sparc/sparc-v9.txt?rev=349048&r1=349047&r2=349048&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Sparc/sparc-v9.txt (original)
+++ llvm/trunk/test/MC/Disassembler/Sparc/sparc-v9.txt Thu Dec 13 07:29:12 2018
@@ -115,4 +115,19 @@
 0x9f 0xd0 0x30 0x52
 
 # CHECK: tvs %xcc, %g1 + %i2   
-0x8f 0xd0 0x50 0x1a
\ No newline at end of file
+0x8f 0xd0 0x50 0x1a
+
+# CHECK: membar 5000
+0x81 0x43 0xf3 0x88
+
+# CHECK: membar #LoadLoad | #StoreLoad | #LoadStore | #StoreStore
+0x81 0x43 0xe0 0x0f
+
+# CHECK: membar #LoadLoad
+0x81 0x43 0xe0 0x01
+
+# CHECK: membar #LoadLoad | #StoreStore
+0x81 0x43 0xe0 0x09
+
+# CHECK: membar #LoadLoad | #StoreLoad | #LoadStore | #StoreStore | #Lookaside | #MemIssue | #Sync
+0x81 0x43 0xe0 0x7f

Modified: llvm/trunk/test/MC/Sparc/sparc-asm-errors.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Sparc/sparc-asm-errors.s?rev=349048&r1=349047&r2=349048&view=diff
==============================================================================
--- llvm/trunk/test/MC/Sparc/sparc-asm-errors.s (original)
+++ llvm/trunk/test/MC/Sparc/sparc-asm-errors.s Thu Dec 13 07:29:12 2018
@@ -1,8 +1,16 @@
-! RUN: not llvm-mc %s -arch=sparc   -show-encoding 2>&1 | FileCheck %s
-! RUN: not llvm-mc %s -arch=sparcv9 -show-encoding 2>&1 | FileCheck %s
+! RUN: not llvm-mc %s -arch=sparc   -show-encoding 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=V8
+! RUN: not llvm-mc %s -arch=sparcv9 -show-encoding 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=V9
 
 ! Test the lower and upper bounds of 'set'
         ! CHECK: argument must be between
         set -2147483649, %o1
         ! CHECK: argument must be between
         set 4294967296, %o1
+
+        ! V8: unexpected token
+        ! V9: unknown membar tag
+        membar #BadTag
+
+        ! V8: instruction requires a CPU feature not currently enabled
+        ! V9: invalid membar mask number
+        membar -127

Modified: llvm/trunk/test/MC/Sparc/sparcv9-atomic-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Sparc/sparcv9-atomic-instructions.s?rev=349048&r1=349047&r2=349048&view=diff
==============================================================================
--- llvm/trunk/test/MC/Sparc/sparcv9-atomic-instructions.s (original)
+++ llvm/trunk/test/MC/Sparc/sparcv9-atomic-instructions.s Thu Dec 13 07:29:12 2018
@@ -1,8 +1,17 @@
 ! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
 
-        ! CHECK: membar 15             ! encoding: [0x81,0x43,0xe0,0x0f]
+        ! CHECK: membar #LoadLoad | #StoreLoad | #LoadStore | #StoreStore  ! encoding: [0x81,0x43,0xe0,0x0f]
         membar 15
 
+        ! CHECK: membar #LoadLoad  ! encoding: [0x81,0x43,0xe0,0x01]
+        membar #LoadLoad
+
+        ! CHECK: membar #LoadLoad | #StoreStore  ! encoding: [0x81,0x43,0xe0,0x09]
+        membar #LoadLoad | #StoreStore
+
+        ! CHECK: membar #LoadLoad | #StoreLoad | #LoadStore | #StoreStore | #Lookaside | #MemIssue | #Sync  ! encoding: [0x81,0x43,0xe0,0x7f]
+        membar #LoadLoad | #StoreLoad | #LoadStore | #StoreStore | #Lookaside | #MemIssue | #Sync
+
         ! CHECK: cas [%i0], %l6, %o2   ! encoding: [0xd5,0xe6,0x10,0x16]
         cas [%i0], %l6, %o2
 




More information about the llvm-commits mailing list