[llvm] 117c0d7 - [VE] Support branch instructions in MC layer

Simon Moll via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 5 06:44:34 PDT 2020


Author: Kazushi (Jam) Marukawa
Date: 2020-06-05T15:44:02+02:00
New Revision: 117c0d7c1c12e5c82e0f5498fec511e8ae08d9ca

URL: https://github.com/llvm/llvm-project/commit/117c0d7c1c12e5c82e0f5498fec511e8ae08d9ca
DIFF: https://github.com/llvm/llvm-project/commit/117c0d7c1c12e5c82e0f5498fec511e8ae08d9ca.diff

LOG: [VE] Support branch instructions in MC layer

Summary:
Add regression tests of asmparser, mccodeemitter, and disassembler for
branch instructions.  In order to support them, we enhance asmparser
by adding splitting mnemonic mechanism, e.g. "bgt.l.t" into "b", "gt",
and ".l.t", and parsing mechanism for AS style memory addressing.
We also implment encoding and decoding mechanism for branch instructions.

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

Added: 
    llvm/test/MC/VE/BC.s
    llvm/test/MC/VE/BCR.s
    llvm/test/MC/VE/BSIC.s

Modified: 
    llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
    llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp
    llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
    llvm/lib/Target/VE/VE.h
    llvm/lib/Target/VE/VEInstrInfo.cpp
    llvm/lib/Target/VE/VEInstrInfo.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
index b2d3831e2668..a1847302347c 100644
--- a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
+++ b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
@@ -67,9 +67,14 @@ class VEAsmParser : public MCTargetAsmParser {
 
   // Custom parse functions for VE specific operands.
   OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
+  OperandMatchResultTy parseMEMAsOperand(OperandVector &Operands);
+  OperandMatchResultTy parseCCOpOperand(OperandVector &Operands);
   OperandMatchResultTy parseMImmOperand(OperandVector &Operands);
   OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
   OperandMatchResultTy parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
+  // Split the mnemonic stripping conditional code and quantifiers
+  StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
+                          OperandVector *Operands);
 
 public:
   VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
@@ -121,8 +126,12 @@ class VEOperand : public MCParsedAsmOperand {
     k_MemoryRegImmImm,  // base=reg, index=imm, disp=imm
     k_MemoryZeroRegImm, // base=0, index=reg, disp=imm
     k_MemoryZeroImmImm, // base=0, index=imm, disp=imm
-    k_MImmOp,           // Special immediate value of sequential bit stream
-                        // of 0 or 1.
+    // SX-Aurora AS form is disp(base).
+    k_MemoryRegImm,  // base=reg, disp=imm
+    k_MemoryZeroImm, // base=0, disp=imm
+    // Other special cases for Aurora VE
+    k_CCOp,   // condition code
+    k_MImmOp, // Special immediate value of sequential bit stream of 0 or 1.
   } Kind;
 
   SMLoc StartLoc, EndLoc;
@@ -147,6 +156,10 @@ class VEOperand : public MCParsedAsmOperand {
     const MCExpr *Offset;
   };
 
+  struct CCOp {
+    unsigned CCVal;
+  };
+
   struct MImmOp {
     const MCExpr *Val;
     bool M0Flag;
@@ -157,6 +170,7 @@ class VEOperand : public MCParsedAsmOperand {
     struct RegOp Reg;
     struct ImmOp Imm;
     struct MemOp Mem;
+    struct CCOp CC;
     struct MImmOp MImm;
   };
 
@@ -174,9 +188,9 @@ class VEOperand : public MCParsedAsmOperand {
   bool isMEMrii() const { return Kind == k_MemoryRegImmImm; }
   bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; }
   bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; }
-  // isMEMri and isMEMzi will be implemented later.
-  bool isMEMri() const { return false; }
-  bool isMEMzi() const { return false; }
+  bool isMEMri() const { return Kind == k_MemoryRegImm; }
+  bool isMEMzi() const { return Kind == k_MemoryZeroImm; }
+  bool isCCOp() const { return Kind == k_CCOp; }
   bool isSImm7() {
     if (!isImm())
       return false;
@@ -216,7 +230,8 @@ class VEOperand : public MCParsedAsmOperand {
   }
 
   unsigned getMemBase() const {
-    assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm) &&
+    assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
+            Kind == k_MemoryRegImm) &&
            "Invalid access!");
     return Mem.Base;
   }
@@ -235,18 +250,25 @@ class VEOperand : public MCParsedAsmOperand {
 
   const MCExpr *getMemOffset() const {
     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
-            Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) &&
+            Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
+            Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
            "Invalid access!");
     return Mem.Offset;
   }
 
   void setMemOffset(const MCExpr *off) {
     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
-            Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) &&
+            Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
+            Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
            "Invalid access!");
     Mem.Offset = off;
   }
 
+  unsigned getCCVal() const {
+    assert((Kind == k_CCOp) && "Invalid access!");
+    return CC.CCVal;
+  }
+
   const MCExpr *getMImmVal() const {
     assert((Kind == k_MImmOp) && "Invalid access!");
     return MImm.Val;
@@ -290,6 +312,17 @@ class VEOperand : public MCParsedAsmOperand {
       assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
       OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n";
       break;
+    case k_MemoryRegImm:
+      assert(getMemOffset() != nullptr);
+      OS << "Mem: #" << getMemBase() << "+" << *getMemOffset() << "\n";
+      break;
+    case k_MemoryZeroImm:
+      assert(getMemOffset() != nullptr);
+      OS << "Mem: 0+" << *getMemOffset() << "\n";
+      break;
+    case k_CCOp:
+      OS << "CCOp: " << getCCVal() << "\n";
+      break;
     case k_MImmOp:
       OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n";
       break;
@@ -354,11 +387,23 @@ class VEOperand : public MCParsedAsmOperand {
   }
 
   void addMEMriOperands(MCInst &Inst, unsigned N) const {
-    // FIXME: implement
+    assert(N == 2 && "Invalid number of operands!");
+
+    Inst.addOperand(MCOperand::createReg(getMemBase()));
+    addExpr(Inst, getMemOffset());
   }
 
   void addMEMziOperands(MCInst &Inst, unsigned N) const {
-    // FIXME: implement
+    assert(N == 2 && "Invalid number of operands!");
+
+    Inst.addOperand(MCOperand::createImm(0));
+    addExpr(Inst, getMemOffset());
+  }
+
+  void addCCOpOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+
+    Inst.addOperand(MCOperand::createImm(getCCVal()));
   }
 
   void addMImmOperands(MCInst &Inst, unsigned N) const {
@@ -398,6 +443,15 @@ class VEOperand : public MCParsedAsmOperand {
     return Op;
   }
 
+  static std::unique_ptr<VEOperand> CreateCCOp(unsigned CCVal, SMLoc S,
+                                               SMLoc E) {
+    auto Op = std::make_unique<VEOperand>(k_CCOp);
+    Op->CC.CCVal = CCVal;
+    Op->StartLoc = S;
+    Op->EndLoc = E;
+    return Op;
+  }
+
   static std::unique_ptr<VEOperand> CreateMImm(const MCExpr *Val, bool Flag,
                                                SMLoc S, SMLoc E) {
     auto Op = std::make_unique<VEOperand>(k_MImmOp);
@@ -426,6 +480,28 @@ class VEOperand : public MCParsedAsmOperand {
     return true;
   }
 
+  static std::unique_ptr<VEOperand>
+  MorphToMEMri(unsigned Base, std::unique_ptr<VEOperand> Op) {
+    const MCExpr *Imm = Op->getImm();
+    Op->Kind = k_MemoryRegImm;
+    Op->Mem.Base = Base;
+    Op->Mem.IndexReg = 0;
+    Op->Mem.Index = nullptr;
+    Op->Mem.Offset = Imm;
+    return Op;
+  }
+
+  static std::unique_ptr<VEOperand>
+  MorphToMEMzi(std::unique_ptr<VEOperand> Op) {
+    const MCExpr *Imm = Op->getImm();
+    Op->Kind = k_MemoryZeroImm;
+    Op->Mem.Base = 0;
+    Op->Mem.IndexReg = 0;
+    Op->Mem.Index = nullptr;
+    Op->Mem.Offset = Imm;
+    return Op;
+  }
+
   static std::unique_ptr<VEOperand>
   MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) {
     const MCExpr *Imm = Op->getImm();
@@ -564,15 +640,72 @@ VEAsmParser::tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
   return MatchOperand_NoMatch;
 }
 
+static StringRef parseCC(StringRef Name, unsigned Prefix, unsigned Suffix,
+                         bool IntegerCC, bool OmitCC, SMLoc NameLoc,
+                         OperandVector *Operands) {
+  // Parse instructions with a conditional code. For example, 'bne' is
+  // converted into two operands 'b' and 'ne'.
+  StringRef Cond = Name.slice(Prefix, Suffix);
+  VECC::CondCode CondCode =
+      IntegerCC ? stringToVEICondCode(Cond) : stringToVEFCondCode(Cond);
+
+  // If OmitCC is enabled, CC_AT and CC_AF is treated as a part of mnemonic.
+  if (CondCode != VECC::UNKNOWN &&
+      (!OmitCC || (CondCode != VECC::CC_AT && CondCode != VECC::CC_AF))) {
+    StringRef SuffixStr = Name.substr(Suffix);
+    // Push "b".
+    Name = Name.slice(0, Prefix);
+    Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
+    // Push $cond part.
+    SMLoc CondLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Prefix);
+    SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Suffix);
+    Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));
+    // push suffix like ".l.t"
+    if (!SuffixStr.empty())
+      Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));
+  } else {
+    Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
+  }
+  return Name;
+}
+
+// Split the mnemonic into ASM operand, conditional code and instruction
+// qualifier (half-word, byte).
+StringRef VEAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
+                                     OperandVector *Operands) {
+  // Create the leading tokens for the mnemonic
+  StringRef Mnemonic = Name;
+
+  if (Name[0] == 'b') {
+    // Match b?? or br??.
+    size_t Start = 1;
+    size_t Next = Name.find('.');
+    // Adjust position of CondCode.
+    if (Name.size() > 1 && Name[1] == 'r')
+      Start = 2;
+    // Check suffix.
+    bool ICC = true;
+    if (Next + 1 < Name.size() &&
+        (Name[Next + 1] == 'd' || Name[Next + 1] == 's'))
+      ICC = false;
+    Mnemonic = parseCC(Name, Start, Next, ICC, true, NameLoc, Operands);
+  } else {
+    Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));
+  }
+
+  return Mnemonic;
+}
+
 bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                                    SMLoc NameLoc, OperandVector &Operands) {
-
-  // First operand in MCInst is instruction mnemonic.
-  Operands.push_back(VEOperand::CreateToken(Name, NameLoc));
+  // Split name to first token and the rest, e.g. "bgt.l.t" to "b", "gt", and
+  // ".l.t".  We treat "b" as a mnemonic, "gt" as first operand, and ".l.t"
+  // as second operand.
+  StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
 
   if (getLexer().isNot(AsmToken::EndOfStatement)) {
     // Read the first operand.
-    if (parseOperand(Operands, Name) != MatchOperand_Success) {
+    if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) {
       SMLoc Loc = getLexer().getLoc();
       return Error(Loc, "unexpected token");
     }
@@ -580,7 +713,7 @@ bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
     while (getLexer().is(AsmToken::Comma)) {
       Parser.Lex(); // Eat the comma.
       // Parse and remember the operand.
-      if (parseOperand(Operands, Name) != MatchOperand_Success) {
+      if (parseOperand(Operands, Mnemonic) != MatchOperand_Success) {
         SMLoc Loc = getLexer().getLoc();
         return Error(Loc, "unexpected token");
       }
@@ -703,6 +836,96 @@ OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) {
   return MatchOperand_Success;
 }
 
+OperandMatchResultTy VEAsmParser::parseMEMAsOperand(OperandVector &Operands) {
+  LLVM_DEBUG(dbgs() << "parseMEMAsOperand\n");
+  const AsmToken &Tok = Parser.getTok();
+  SMLoc S = Tok.getLoc();
+  SMLoc E = Tok.getEndLoc();
+  // Parse AS format
+  //   disp
+  //   disp(, base)
+  //   disp(base)
+  //   disp()
+  //   (, base)
+  //   (base)
+  //   base
+
+  unsigned BaseReg = VE::NoRegister;
+  std::unique_ptr<VEOperand> Offset;
+  switch (getLexer().getKind()) {
+  default:
+    return MatchOperand_NoMatch;
+
+  case AsmToken::Minus:
+  case AsmToken::Integer:
+  case AsmToken::Dot: {
+    const MCExpr *EVal;
+    if (!getParser().parseExpression(EVal, E))
+      Offset = VEOperand::CreateImm(EVal, S, E);
+    else
+      return MatchOperand_NoMatch;
+    break;
+  }
+
+  case AsmToken::Percent:
+    if (ParseRegister(BaseReg, S, E))
+      return MatchOperand_NoMatch;
+    Offset =
+        VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
+    break;
+
+  case AsmToken::LParen:
+    // empty disp (= 0)
+    Offset =
+        VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
+    break;
+  }
+
+  switch (getLexer().getKind()) {
+  default:
+    return MatchOperand_ParseFail;
+
+  case AsmToken::EndOfStatement:
+  case AsmToken::Comma:
+    Operands.push_back(BaseReg != VE::NoRegister
+                           ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
+                           : VEOperand::MorphToMEMzi(std::move(Offset)));
+    return MatchOperand_Success;
+
+  case AsmToken::LParen:
+    if (BaseReg != VE::NoRegister)
+      return MatchOperand_ParseFail;
+    Parser.Lex(); // Eat the (
+    break;
+  }
+
+  switch (getLexer().getKind()) {
+  default:
+    if (ParseRegister(BaseReg, S, E))
+      return MatchOperand_ParseFail;
+    break;
+
+  case AsmToken::Comma:
+    Parser.Lex(); // Eat the ,
+    if (ParseRegister(BaseReg, S, E))
+      return MatchOperand_ParseFail;
+    break;
+
+  case AsmToken::RParen:
+    break;
+  }
+
+  if (!Parser.getTok().is(AsmToken::RParen))
+    return MatchOperand_ParseFail;
+
+  Parser.Lex(); // Eat the )
+  Operands.push_back(BaseReg != VE::NoRegister
+                         ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
+                         : VEOperand::MorphToMEMzi(std::move(Offset)));
+
+  return MatchOperand_Success;
+}
+
 OperandMatchResultTy VEAsmParser::parseMImmOperand(OperandVector &Operands) {
   LLVM_DEBUG(dbgs() << "parseMImmOperand\n");
 

diff  --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp
index fbece1d758fc..b8ad4d99d49d 100644
--- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp
+++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp
@@ -131,8 +131,18 @@ static DecodeStatus DecodeLoadF32(MCInst &Inst, uint64_t insn, uint64_t Address,
                                   const void *Decoder);
 static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
                                    uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
+                               const void *Decoder);
 static DecodeStatus DecodeSIMM7(MCInst &Inst, uint64_t insn, uint64_t Address,
                                 const void *Decoder);
+static DecodeStatus DecodeCCOperand(MCInst &Inst, uint64_t insn,
+                                    uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeBranchCondition(MCInst &Inst, uint64_t insn,
+                                          uint64_t Address,
+                                          const void *Decoder);
+static DecodeStatus DecodeBranchConditionAlways(MCInst &Inst, uint64_t insn,
+                                                uint64_t Address,
+                                                const void *Decoder);
 
 #include "VEGenDisassemblerTables.inc"
 
@@ -218,6 +228,28 @@ static DecodeStatus DecodeASX(MCInst &MI, uint64_t insn, uint64_t Address,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeAS(MCInst &MI, uint64_t insn, uint64_t Address,
+                             const void *Decoder) {
+  unsigned sz = fieldFromInstruction(insn, 32, 7);
+  bool cz = fieldFromInstruction(insn, 39, 1);
+  uint64_t simm32 = SignExtend64<32>(fieldFromInstruction(insn, 0, 32));
+  DecodeStatus status;
+
+  // Decode sz.
+  if (cz) {
+    status = DecodeI64RegisterClass(MI, sz, Address, Decoder);
+    if (status != MCDisassembler::Success)
+      return status;
+  } else {
+    MI.addOperand(MCOperand::createImm(0));
+  }
+
+  // Decode simm32.
+  MI.addOperand(MCOperand::createImm(simm32));
+
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeMem(MCInst &MI, uint64_t insn, uint64_t Address,
                               const void *Decoder, bool isLoad,
                               DecodeFunc DecodeSX) {
@@ -272,9 +304,89 @@ static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
   return DecodeMem(Inst, insn, Address, Decoder, false, DecodeF32RegisterClass);
 }
 
+static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
+                               const void *Decoder) {
+  return DecodeMem(Inst, insn, Address, Decoder, true, DecodeI64RegisterClass);
+}
+
 static DecodeStatus DecodeSIMM7(MCInst &MI, uint64_t insn, uint64_t Address,
                                 const void *Decoder) {
   uint64_t tgt = SignExtend64<7>(insn);
   MI.addOperand(MCOperand::createImm(tgt));
   return MCDisassembler::Success;
 }
+
+static bool isIntegerBCKind(MCInst &MI) {
+
+#define BCm_kind(NAME)                                                         \
+  case NAME##rri:                                                              \
+  case NAME##rzi:                                                              \
+  case NAME##iri:                                                              \
+  case NAME##izi:                                                              \
+  case NAME##rri_nt:                                                           \
+  case NAME##rzi_nt:                                                           \
+  case NAME##iri_nt:                                                           \
+  case NAME##izi_nt:                                                           \
+  case NAME##rri_t:                                                            \
+  case NAME##rzi_t:                                                            \
+  case NAME##iri_t:                                                            \
+  case NAME##izi_t:
+
+#define BCRm_kind(NAME)                                                        \
+  case NAME##rr:                                                               \
+  case NAME##ir:                                                               \
+  case NAME##rr_nt:                                                            \
+  case NAME##ir_nt:                                                            \
+  case NAME##rr_t:                                                             \
+  case NAME##ir_t:
+
+  {
+    using namespace llvm::VE;
+    switch (MI.getOpcode()) {
+      BCm_kind(BCFL) BCm_kind(BCFW) BCRm_kind(BRCFL)
+          BCRm_kind(BRCFW) return true;
+    }
+  }
+#undef BCm_kind
+
+  return false;
+}
+
+// Decode CC Operand field.
+static DecodeStatus DecodeCCOperand(MCInst &MI, uint64_t cf, uint64_t Address,
+                                    const void *Decoder) {
+  MI.addOperand(MCOperand::createImm(VEValToCondCode(cf, isIntegerBCKind(MI))));
+  return MCDisassembler::Success;
+}
+
+// Decode branch condition instruction and CCOperand field in it.
+static DecodeStatus DecodeBranchCondition(MCInst &MI, uint64_t insn,
+                                          uint64_t Address,
+                                          const void *Decoder) {
+  unsigned cf = fieldFromInstruction(insn, 48, 4);
+  bool cy = fieldFromInstruction(insn, 47, 1);
+  unsigned sy = fieldFromInstruction(insn, 40, 7);
+
+  // Decode cf.
+  MI.addOperand(MCOperand::createImm(VEValToCondCode(cf, isIntegerBCKind(MI))));
+
+  // Decode sy.
+  DecodeStatus status;
+  if (cy) {
+    status = DecodeI64RegisterClass(MI, sy, Address, Decoder);
+    if (status != MCDisassembler::Success)
+      return status;
+  } else {
+    MI.addOperand(MCOperand::createImm(SignExtend32<7>(sy)));
+  }
+
+  // Decode MEMri.
+  return DecodeAS(MI, insn, Address, Decoder);
+}
+
+static DecodeStatus DecodeBranchConditionAlways(MCInst &MI, uint64_t insn,
+                                                uint64_t Address,
+                                                const void *Decoder) {
+  // Decode MEMri.
+  return DecodeAS(MI, insn, Address, Decoder);
+}

diff  --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
index b8328c6cb58d..c32f5564bb90 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
@@ -65,6 +65,10 @@ class VEMCCodeEmitter : public MCCodeEmitter {
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
 
+  uint64_t getCCOpValue(const MCInst &MI, unsigned OpNo,
+                        SmallVectorImpl<MCFixup> &Fixups,
+                        const MCSubtargetInfo &STI) const;
+
 private:
   FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
   void
@@ -112,6 +116,16 @@ unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst &MI,
   return 0;
 }
 
+uint64_t VEMCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned OpNo,
+                                       SmallVectorImpl<MCFixup> &Fixups,
+                                       const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+  if (MO.isImm())
+    return VECondCodeToVal(
+        static_cast<VECC::CondCode>(getMachineOpValue(MI, MO, Fixups, STI)));
+  return 0;
+}
+
 #define ENABLE_INSTR_PREDICATE_VERIFIER
 #include "VEGenMCCodeEmitter.inc"
 

diff  --git a/llvm/lib/Target/VE/VE.h b/llvm/lib/Target/VE/VE.h
index db33d1c25258..960a04355b96 100644
--- a/llvm/lib/Target/VE/VE.h
+++ b/llvm/lib/Target/VE/VE.h
@@ -15,6 +15,7 @@
 #define LLVM_LIB_TARGET_VE_VE_H
 
 #include "MCTargetDesc/VEMCTargetDesc.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Target/TargetMachine.h"
 
@@ -39,30 +40,31 @@ namespace llvm {
 namespace VECC {
 enum CondCode {
   // Integer comparison
-  CC_IG =  0,  // Greater
-  CC_IL =  1,  // Less
+  CC_IG = 0,  // Greater
+  CC_IL = 1,  // Less
   CC_INE = 2, // Not Equal
   CC_IEQ = 3, // Equal
   CC_IGE = 4, // Greater or Equal
   CC_ILE = 5, // Less or Equal
 
   // Floating point comparison
-  CC_AF =     0 + 6, // Never
-  CC_G =      1 + 6, // Greater
-  CC_L =      2 + 6, // Less
-  CC_NE =     3 + 6, // Not Equal
-  CC_EQ =     4 + 6, // Equal
-  CC_GE =     5 + 6, // Greater or Equal
-  CC_LE =     6 + 6, // Less or Equal
-  CC_NUM =    7 + 6, // Number
-  CC_NAN =    8 + 6, // NaN
-  CC_GNAN =   9 + 6, // Greater or NaN
-  CC_LNAN =  10 + 6, // Less or NaN
+  CC_AF = 0 + 6,     // Never
+  CC_G = 1 + 6,      // Greater
+  CC_L = 2 + 6,      // Less
+  CC_NE = 3 + 6,     // Not Equal
+  CC_EQ = 4 + 6,     // Equal
+  CC_GE = 5 + 6,     // Greater or Equal
+  CC_LE = 6 + 6,     // Less or Equal
+  CC_NUM = 7 + 6,    // Number
+  CC_NAN = 8 + 6,    // NaN
+  CC_GNAN = 9 + 6,   // Greater or NaN
+  CC_LNAN = 10 + 6,  // Less or NaN
   CC_NENAN = 11 + 6, // Not Equal or NaN
   CC_EQNAN = 12 + 6, // Equal or NaN
   CC_GENAN = 13 + 6, // Greater or Equal or NaN
   CC_LENAN = 14 + 6, // Less or Equal or NaN
-  CC_AT =    15 + 6, // Always
+  CC_AT = 15 + 6,    // Always
+  UNKNOWN
 };
 }
 // Enums corresponding to VE Rounding Mode.  These values must be kept in
@@ -103,6 +105,153 @@ inline static const char *VECondCodeToString(VECC::CondCode CC) {
   case VECC::CC_GENAN: return "genan";
   case VECC::CC_LENAN: return "lenan";
   case VECC::CC_AT:    return "at";
+  default:
+    llvm_unreachable("Invalid cond code");
+  }
+}
+
+inline static VECC::CondCode stringToVEICondCode(StringRef S) {
+  return StringSwitch<VECC::CondCode>(S)
+      .Case("gt", VECC::CC_IG)
+      .Case("lt", VECC::CC_IL)
+      .Case("ne", VECC::CC_INE)
+      .Case("eq", VECC::CC_IEQ)
+      .Case("ge", VECC::CC_IGE)
+      .Case("le", VECC::CC_ILE)
+      .Case("af", VECC::CC_AF)
+      .Case("at", VECC::CC_AT)
+      .Case("", VECC::CC_AT)
+      .Default(VECC::UNKNOWN);
+}
+
+inline static VECC::CondCode stringToVEFCondCode(StringRef S) {
+  return StringSwitch<VECC::CondCode>(S)
+      .Case("gt", VECC::CC_G)
+      .Case("lt", VECC::CC_L)
+      .Case("ne", VECC::CC_NE)
+      .Case("eq", VECC::CC_EQ)
+      .Case("ge", VECC::CC_GE)
+      .Case("le", VECC::CC_LE)
+      .Case("num", VECC::CC_NUM)
+      .Case("nan", VECC::CC_NAN)
+      .Case("gtnan", VECC::CC_GNAN)
+      .Case("ltnan", VECC::CC_LNAN)
+      .Case("nenan", VECC::CC_NENAN)
+      .Case("eqnan", VECC::CC_EQNAN)
+      .Case("genan", VECC::CC_GENAN)
+      .Case("lenan", VECC::CC_LENAN)
+      .Case("af", VECC::CC_AF)
+      .Case("at", VECC::CC_AT)
+      .Case("", VECC::CC_AT)
+      .Default(VECC::UNKNOWN);
+}
+
+inline static unsigned VECondCodeToVal(VECC::CondCode CC) {
+  switch (CC) {
+  case VECC::CC_IG:
+    return 1;
+  case VECC::CC_IL:
+    return 2;
+  case VECC::CC_INE:
+    return 3;
+  case VECC::CC_IEQ:
+    return 4;
+  case VECC::CC_IGE:
+    return 5;
+  case VECC::CC_ILE:
+    return 6;
+  case VECC::CC_AF:
+    return 0;
+  case VECC::CC_G:
+    return 1;
+  case VECC::CC_L:
+    return 2;
+  case VECC::CC_NE:
+    return 3;
+  case VECC::CC_EQ:
+    return 4;
+  case VECC::CC_GE:
+    return 5;
+  case VECC::CC_LE:
+    return 6;
+  case VECC::CC_NUM:
+    return 7;
+  case VECC::CC_NAN:
+    return 8;
+  case VECC::CC_GNAN:
+    return 9;
+  case VECC::CC_LNAN:
+    return 10;
+  case VECC::CC_NENAN:
+    return 11;
+  case VECC::CC_EQNAN:
+    return 12;
+  case VECC::CC_GENAN:
+    return 13;
+  case VECC::CC_LENAN:
+    return 14;
+  case VECC::CC_AT:
+    return 15;
+  default:
+    llvm_unreachable("Invalid cond code");
+  }
+}
+
+inline static VECC::CondCode VEValToCondCode(unsigned Val, bool IsInteger) {
+  if (IsInteger) {
+    switch (Val) {
+    case 0:
+      return VECC::CC_AF;
+    case 1:
+      return VECC::CC_IG;
+    case 2:
+      return VECC::CC_IL;
+    case 3:
+      return VECC::CC_INE;
+    case 4:
+      return VECC::CC_IEQ;
+    case 5:
+      return VECC::CC_IGE;
+    case 6:
+      return VECC::CC_ILE;
+    case 15:
+      return VECC::CC_AT;
+    }
+  } else {
+    switch (Val) {
+    case 0:
+      return VECC::CC_AF;
+    case 1:
+      return VECC::CC_G;
+    case 2:
+      return VECC::CC_L;
+    case 3:
+      return VECC::CC_NE;
+    case 4:
+      return VECC::CC_EQ;
+    case 5:
+      return VECC::CC_GE;
+    case 6:
+      return VECC::CC_LE;
+    case 7:
+      return VECC::CC_NUM;
+    case 8:
+      return VECC::CC_NAN;
+    case 9:
+      return VECC::CC_GNAN;
+    case 10:
+      return VECC::CC_LNAN;
+    case 11:
+      return VECC::CC_NENAN;
+    case 12:
+      return VECC::CC_EQNAN;
+    case 13:
+      return VECC::CC_GENAN;
+    case 14:
+      return VECC::CC_LENAN;
+    case 15:
+      return VECC::CC_AT;
+    }
   }
   llvm_unreachable("Invalid cond code");
 }

diff  --git a/llvm/lib/Target/VE/VEInstrInfo.cpp b/llvm/lib/Target/VE/VEInstrInfo.cpp
index aa19c6ce0687..91fecf00959f 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.cpp
+++ b/llvm/lib/Target/VE/VEInstrInfo.cpp
@@ -41,29 +41,53 @@ VEInstrInfo::VEInstrInfo(VESubtarget &ST)
 static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); }
 
 static VECC::CondCode GetOppositeBranchCondition(VECC::CondCode CC) {
-  switch(CC) {
-  case VECC::CC_IG:     return VECC::CC_ILE;
-  case VECC::CC_IL:     return VECC::CC_IGE;
-  case VECC::CC_INE:    return VECC::CC_IEQ;
-  case VECC::CC_IEQ:    return VECC::CC_INE;
-  case VECC::CC_IGE:    return VECC::CC_IL;
-  case VECC::CC_ILE:    return VECC::CC_IG;
-  case VECC::CC_AF:     return VECC::CC_AT;
-  case VECC::CC_G:      return VECC::CC_LENAN;
-  case VECC::CC_L:      return VECC::CC_GENAN;
-  case VECC::CC_NE:     return VECC::CC_EQNAN;
-  case VECC::CC_EQ:     return VECC::CC_NENAN;
-  case VECC::CC_GE:     return VECC::CC_LNAN;
-  case VECC::CC_LE:     return VECC::CC_GNAN;
-  case VECC::CC_NUM:    return VECC::CC_NAN;
-  case VECC::CC_NAN:    return VECC::CC_NUM;
-  case VECC::CC_GNAN:   return VECC::CC_LE;
-  case VECC::CC_LNAN:   return VECC::CC_GE;
-  case VECC::CC_NENAN:  return VECC::CC_EQ;
-  case VECC::CC_EQNAN:  return VECC::CC_NE;
-  case VECC::CC_GENAN:  return VECC::CC_L;
-  case VECC::CC_LENAN:  return VECC::CC_G;
-  case VECC::CC_AT:     return VECC::CC_AF;
+  switch (CC) {
+  case VECC::CC_IG:
+    return VECC::CC_ILE;
+  case VECC::CC_IL:
+    return VECC::CC_IGE;
+  case VECC::CC_INE:
+    return VECC::CC_IEQ;
+  case VECC::CC_IEQ:
+    return VECC::CC_INE;
+  case VECC::CC_IGE:
+    return VECC::CC_IL;
+  case VECC::CC_ILE:
+    return VECC::CC_IG;
+  case VECC::CC_AF:
+    return VECC::CC_AT;
+  case VECC::CC_G:
+    return VECC::CC_LENAN;
+  case VECC::CC_L:
+    return VECC::CC_GENAN;
+  case VECC::CC_NE:
+    return VECC::CC_EQNAN;
+  case VECC::CC_EQ:
+    return VECC::CC_NENAN;
+  case VECC::CC_GE:
+    return VECC::CC_LNAN;
+  case VECC::CC_LE:
+    return VECC::CC_GNAN;
+  case VECC::CC_NUM:
+    return VECC::CC_NAN;
+  case VECC::CC_NAN:
+    return VECC::CC_NUM;
+  case VECC::CC_GNAN:
+    return VECC::CC_LE;
+  case VECC::CC_LNAN:
+    return VECC::CC_GE;
+  case VECC::CC_NENAN:
+    return VECC::CC_EQ;
+  case VECC::CC_EQNAN:
+    return VECC::CC_NE;
+  case VECC::CC_GENAN:
+    return VECC::CC_L;
+  case VECC::CC_LENAN:
+    return VECC::CC_G;
+  case VECC::CC_AT:
+    return VECC::CC_AF;
+  case VECC::UNKNOWN:
+    return VECC::UNKNOWN;
   }
   llvm_unreachable("Invalid cond code");
 }

diff  --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
index 27eb11c8dea8..46226b5ae8a2 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.td
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -95,6 +95,11 @@ def fcond2ccSwap : SDNodeXForm<cond, [{
   return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
 }]>;
 
+def CCOP : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(N->getZExtValue(),
+                                   SDLoc(N), MVT::i32);
+}]>;
+
 //===----------------------------------------------------------------------===//
 // Feature predicates.
 //===----------------------------------------------------------------------===//
@@ -261,9 +266,11 @@ def MEMzii : Operand<iPTR> {
 // AS assembly instruction format:
 def VEMEMriAsmOperand : AsmOperandClass {
   let Name = "MEMri";
+  let ParserMethod = "parseMEMAsOperand";
 }
 def VEMEMziAsmOperand : AsmOperandClass {
   let Name = "MEMzi";
+  let ParserMethod = "parseMEMAsOperand";
 }
 // AS generic assembly instruction format:
 def MEMriASX : Operand<iPTR> {
@@ -290,8 +297,14 @@ def calltarget : Operand<i64> {
 }
 
 // Operand for printing out a condition code.
-let PrintMethod = "printCCOperand" in
-  def CCOp : Operand<i32>;
+def CCOpAsmOperand : AsmOperandClass { let Name = "CCOp"; }
+def CCOp : Operand<i32>, ImmLeaf<i32, [{
+    return Imm >= 0 && Imm < 22; }], CCOP> {
+  let PrintMethod = "printCCOperand";
+  let DecoderMethod = "DecodeCCOperand";
+  let EncoderMethod = "getCCOpValue";
+  let ParserMatchClass = CCOpAsmOperand;
+}
 
 // Operand for printing out a rounding mode code.
 def RDOp : Operand<i32> {
@@ -586,13 +599,14 @@ multiclass BCtgm<string opcStr, string cmpStr, bits<8> opc, dag cond> {
 }
 multiclass BCm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc,
                RegisterClass RC, Operand immOp> {
+  let DecoderMethod = "DecodeBranchCondition" in
   defm r : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, RC:$comp)>;
-  let cy = 0 in
+  let DecoderMethod = "DecodeBranchCondition", cy = 0 in
   defm i : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, immOp:$comp)>;
-  let cy = 0, sy = 0,
+  let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0,
       cf = 15 /* AT */, isBarrier = 1 in
   defm a : BCtgm<opcStrAt, "", opc, (ins)>;
-  let cy = 0, sy = 0,
+  let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0,
       cf = 0 /* AF */ in
   defm na : BCtgm<opcStrAf, "", opc, (ins)>;
 }
@@ -1044,7 +1058,7 @@ let cx = 1, cx2 = 1 in
 defm BRCFS : BCRm<"br${cf}.s", "br.s", "braf.s", 0x18, F32, simm7fp>;
 
 // Section 8.8.5 - BSIC (Branch and Save IC)
-let isCall = 1, hasSideEffects = 0 in
+let isCall = 1, hasSideEffects = 0, DecoderMethod = "DecodeCall" in
 defm BSIC : RMm<"bsic", 0x08, I64>;
 
 // Call instruction is a special case of BSIC.

diff  --git a/llvm/test/MC/VE/BC.s b/llvm/test/MC/VE/BC.s
new file mode 100644
index 000000000000..68914b5b5124
--- /dev/null
+++ b/llvm/test/MC/VE/BC.s
@@ -0,0 +1,120 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: b.l 8199
+# CHECK-ENCODING: encoding: [0x07,0x20,0x00,0x00,0x00,0x00,0x0f,0x19]
+b.l 8199
+
+# CHECK-INST: b.l.t 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x00,0x3f,0x19]
+b.l.t 20(, %s11)
+
+# CHECK-INST: baf.l.nt -1(, %s11)
+# CHECK-ENCODING: encoding: [0xff,0xff,0xff,0xff,0x8b,0x00,0x20,0x19]
+baf.l.nt -1(, %s11)
+
+# CHECK-INST: b.w.t 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x00,0x3f,0x1b]
+b.w.t 20(, %s11)
+
+# CHECK-INST: baf.d.nt -1(, %s11)
+# CHECK-ENCODING: encoding: [0xff,0xff,0xff,0xff,0x8b,0x00,0x20,0x1c]
+baf.d.nt -1(, %s11)
+
+# CHECK-INST: b.s.t 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x00,0xbf,0x1c]
+b.s.t 20(,%s11)
+
+# CHECK-INST: bgt.d %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x01,0x1c]
+bgt.d %s20, 20(, %s11)
+
+# CHECK-INST: bgt.l.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0x31,0x19]
+bgt.l.t %s20, 8192
+
+# CHECK-INST: bgt.d.nt %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x21,0x1c]
+bgt.d.nt %s20, 20(, %s11)
+
+# CHECK-INST: blt.w.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0x32,0x1b]
+blt.w.t %s20, 8192
+
+# CHECK-INST: blt.s.nt %s20, (, %s11)
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x8b,0x94,0xa2,0x1c]
+blt.s.nt %s20, (, %s11)
+
+# CHECK-INST: bne.l.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0x33,0x19]
+bne.l.t %s20, 8192
+
+# CHECK-INST: bne.d.nt %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x23,0x1c]
+bne.d.nt %s20, 20(, %s11)
+
+# CHECK-INST: beq.w.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0x34,0x1b]
+beq.w.t %s20, 8192
+
+# CHECK-INST: beq.s.nt %s20, (, %s11)
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x8b,0x94,0xa4,0x1c]
+beq.s.nt %s20, (,%s11)
+
+# CHECK-INST: bge.l.t 63, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x3f,0x35,0x19]
+bge.l.t 63, 8192
+
+# CHECK-INST: bge.d.nt -64, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x40,0x25,0x1c]
+bge.d.nt -64, 20(, %s11)
+
+# CHECK-INST: ble.w.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0x36,0x1b]
+ble.w.t %s20, 8192
+
+# CHECK-INST: ble.s.nt %s20, (, %s11)
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x8b,0x94,0xa6,0x1c]
+ble.s.nt %s20, (,%s11)
+
+# CHECK-INST: bnum.s.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0xb7,0x1c]
+bnum.s.t %s20, 8192
+
+# CHECK-INST: bnum.d.nt %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x27,0x1c]
+bnum.d.nt %s20, 20(, %s11)
+
+# CHECK-INST: bnan.s.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0xb8,0x1c]
+bnan.s.t %s20, 8192
+
+# CHECK-INST: bnan.d.nt %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x28,0x1c]
+bnan.d.nt %s20, 20(, %s11)
+
+# CHECK-INST: bgtnan.s.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0xb9,0x1c]
+bgtnan.s.t %s20, 8192
+
+# CHECK-INST: bltnan.d.nt %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x2a,0x1c]
+bltnan.d.nt %s20, 20(, %s11)
+
+# CHECK-INST: bnenan.s.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0xbb,0x1c]
+bnenan.s.t %s20, 8192
+
+# CHECK-INST: beqnan.d.nt %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x2c,0x1c]
+beqnan.d.nt %s20, 20(, %s11)
+
+# CHECK-INST: bgenan.s.t %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x00,0x94,0xbd,0x1c]
+bgenan.s.t %s20, 8192
+
+# CHECK-INST: blenan.d.nt %s20, 20(, %s11)
+# CHECK-ENCODING: encoding: [0x14,0x00,0x00,0x00,0x8b,0x94,0x2e,0x1c]
+blenan.d.nt %s20, 20(, %s11)

diff  --git a/llvm/test/MC/VE/BCR.s b/llvm/test/MC/VE/BCR.s
new file mode 100644
index 000000000000..016e13630d1d
--- /dev/null
+++ b/llvm/test/MC/VE/BCR.s
@@ -0,0 +1,72 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: br.l 8199
+# CHECK-ENCODING: encoding: [0x07,0x20,0x00,0x00,0x00,0x00,0x0f,0x18]
+br.l 8199
+
+# CHECK-INST: br.w.t -224
+# CHECK-ENCODING: encoding: [0x20,0xff,0xff,0xff,0x00,0x00,0xbf,0x18]
+br.w.t -224
+
+# CHECK-INST: braf.d.nt 224
+# CHECK-ENCODING: encoding: [0xe0,0x00,0x00,0x00,0x00,0x00,0x60,0x18]
+braf.d.nt 224
+
+# CHECK-INST: brgt.s 23, %s20, 224
+# CHECK-ENCODING: encoding: [0xe0,0x00,0x00,0x00,0x94,0x17,0xc1,0x18]
+brgt.s 23, %s20, 224
+
+# CHECK-INST: brlt.l.t 23, %s20, -224
+# CHECK-ENCODING: encoding: [0x20,0xff,0xff,0xff,0x94,0x17,0x32,0x18]
+brlt.l.t 23, %s20, -224
+
+# CHECK-INST: brne.w.nt 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0xa3,0x18]
+brne.w.nt 23, %s20, 8192
+
+# CHECK-INST: breq.d 23, %s20, -224
+# CHECK-ENCODING: encoding: [0x20,0xff,0xff,0xff,0x94,0x17,0x44,0x18]
+breq.d 23, %s20, -224
+
+# CHECK-INST: brge.s.t 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0xf5,0x18]
+brge.s.t 23, %s20, 8192
+
+# CHECK-INST: brle.l.nt 23, %s20, 224
+# CHECK-ENCODING: encoding: [0xe0,0x00,0x00,0x00,0x94,0x17,0x26,0x18]
+brle.l.nt 23, %s20, 224
+
+# CHECK-INST: brnum.d 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0x47,0x18]
+brnum.d 23, %s20, 8192
+
+# CHECK-INST: brnan.s.t 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0xf8,0x18]
+brnan.s.t 23, %s20, 8192
+
+# CHECK-INST: brgtnan.d.nt 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0x69,0x18]
+brgtnan.d.nt 23, %s20, 8192
+
+# CHECK-INST: brltnan.s 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0xca,0x18]
+brltnan.s 23, %s20, 8192
+
+# CHECK-INST: brnenan.d.t 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0x7b,0x18]
+brnenan.d.t 23, %s20, 8192
+
+# CHECK-INST: breqnan.s.nt 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0xec,0x18]
+breqnan.s.nt 23, %s20, 8192
+
+# CHECK-INST: brgenan.d 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0x4d,0x18]
+brgenan.d 23, %s20, 8192
+
+# CHECK-INST: brlenan.s.t 23, %s20, 8192
+# CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0xfe,0x18]
+brlenan.s.t 23, %s20, 8192

diff  --git a/llvm/test/MC/VE/BSIC.s b/llvm/test/MC/VE/BSIC.s
new file mode 100644
index 000000000000..ec61a570674c
--- /dev/null
+++ b/llvm/test/MC/VE/BSIC.s
@@ -0,0 +1,28 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: bsic %s11, 23
+# CHECK-ENCODING: encoding: [0x17,0x00,0x00,0x00,0x00,0x00,0x0b,0x08]
+bsic %s11, 23
+
+# CHECK-INST: bsic %s63, 324(, %s11)
+# CHECK-ENCODING: encoding: [0x44,0x01,0x00,0x00,0x8b,0x00,0x3f,0x08]
+bsic %s63, 324(,%s11)
+
+# CHECK-INST: bsic %s11, 324(%s10)
+# CHECK-ENCODING: encoding: [0x44,0x01,0x00,0x00,0x00,0x8a,0x0b,0x08]
+bsic %s11, 324(%s10  )
+
+# CHECK-INST: bsic %s11, 324(%s13, %s11)
+# CHECK-ENCODING: encoding: [0x44,0x01,0x00,0x00,0x8b,0x8d,0x0b,0x08]
+bsic %s11, 324 (%s13,%s11)
+
+# CHECK-INST: bsic %s11, (%s10)
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x00,0x8a,0x0b,0x08]
+bsic %s11, (%s10)
+
+# CHECK-INST: bsic %s11, (, %s12)
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x8c,0x00,0x0b,0x08]
+bsic %s11, (,%s12)


        


More information about the llvm-commits mailing list