summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/PowerPC/AsmParser/CMakeLists.txt8
-rw-r--r--llvm/lib/Target/PowerPC/AsmParser/LLVMBuild.txt23
-rw-r--r--llvm/lib/Target/PowerPC/AsmParser/Makefile15
-rw-r--r--llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp681
-rw-r--r--llvm/lib/Target/PowerPC/CMakeLists.txt2
-rw-r--r--llvm/lib/Target/PowerPC/LLVMBuild.txt2
-rw-r--r--llvm/lib/Target/PowerPC/Makefile4
-rw-r--r--llvm/lib/Target/PowerPC/PPC.td5
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstr64Bit.td4
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstrInfo.td125
-rw-r--r--llvm/test/MC/PowerPC/ppc64-encoding-fp.s263
-rw-r--r--llvm/test/MC/PowerPC/ppc64-encoding-vmx.s384
-rw-r--r--llvm/test/MC/PowerPC/ppc64-encoding.s480
-rw-r--r--llvm/test/MC/PowerPC/ppc64-errors.s80
-rw-r--r--llvm/test/MC/PowerPC/ppc64-operands.s87
15 files changed, 2147 insertions, 16 deletions
diff --git a/llvm/lib/Target/PowerPC/AsmParser/CMakeLists.txt b/llvm/lib/Target/PowerPC/AsmParser/CMakeLists.txt
new file mode 100644
index 00000000000..3aa59c00c36
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/AsmParser/CMakeLists.txt
@@ -0,0 +1,8 @@
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+add_llvm_library(LLVMPowerPCAsmParser
+ PPCAsmParser.cpp
+ )
+
+add_dependencies(LLVMPowerPCAsmParser PowerPCCommonTableGen)
diff --git a/llvm/lib/Target/PowerPC/AsmParser/LLVMBuild.txt b/llvm/lib/Target/PowerPC/AsmParser/LLVMBuild.txt
new file mode 100644
index 00000000000..bd08c132b7e
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/AsmParser/LLVMBuild.txt
@@ -0,0 +1,23 @@
+;===- ./lib/Target/PowerPC/AsmParser/LLVMBuild.txt --------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = PowerPCAsmParser
+parent = PowerPC
+required_libraries = PowerPCInfo MC MCParser Support
+add_to_library_groups = PowerPC
diff --git a/llvm/lib/Target/PowerPC/AsmParser/Makefile b/llvm/lib/Target/PowerPC/AsmParser/Makefile
new file mode 100644
index 00000000000..c8a8915685e
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/AsmParser/Makefile
@@ -0,0 +1,15 @@
+##===- lib/Target/PowerPC/AsmParser/Makefile ----------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../../../..
+LIBRARYNAME = LLVMPowerPCAsmParser
+
+# Hack: we need to include 'main' PowerPC target directory to grab private headers
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+
+include $(LEVEL)/Makefile.common
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
new file mode 100644
index 00000000000..c69803aae9d
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -0,0 +1,681 @@
+//===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/PPCMCTargetDesc.h"
+#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+
+static unsigned RRegs[32] = {
+ PPC::R0, PPC::R1, PPC::R2, PPC::R3,
+ PPC::R4, PPC::R5, PPC::R6, PPC::R7,
+ PPC::R8, PPC::R9, PPC::R10, PPC::R11,
+ PPC::R12, PPC::R13, PPC::R14, PPC::R15,
+ PPC::R16, PPC::R17, PPC::R18, PPC::R19,
+ PPC::R20, PPC::R21, PPC::R22, PPC::R23,
+ PPC::R24, PPC::R25, PPC::R26, PPC::R27,
+ PPC::R28, PPC::R29, PPC::R30, PPC::R31
+};
+static unsigned RRegsNoR0[32] = {
+ PPC::ZERO,
+ PPC::R1, PPC::R2, PPC::R3,
+ PPC::R4, PPC::R5, PPC::R6, PPC::R7,
+ PPC::R8, PPC::R9, PPC::R10, PPC::R11,
+ PPC::R12, PPC::R13, PPC::R14, PPC::R15,
+ PPC::R16, PPC::R17, PPC::R18, PPC::R19,
+ PPC::R20, PPC::R21, PPC::R22, PPC::R23,
+ PPC::R24, PPC::R25, PPC::R26, PPC::R27,
+ PPC::R28, PPC::R29, PPC::R30, PPC::R31
+};
+static unsigned XRegs[32] = {
+ PPC::X0, PPC::X1, PPC::X2, PPC::X3,
+ PPC::X4, PPC::X5, PPC::X6, PPC::X7,
+ PPC::X8, PPC::X9, PPC::X10, PPC::X11,
+ PPC::X12, PPC::X13, PPC::X14, PPC::X15,
+ PPC::X16, PPC::X17, PPC::X18, PPC::X19,
+ PPC::X20, PPC::X21, PPC::X22, PPC::X23,
+ PPC::X24, PPC::X25, PPC::X26, PPC::X27,
+ PPC::X28, PPC::X29, PPC::X30, PPC::X31
+};
+static unsigned XRegsNoX0[32] = {
+ PPC::ZERO8,
+ PPC::X1, PPC::X2, PPC::X3,
+ PPC::X4, PPC::X5, PPC::X6, PPC::X7,
+ PPC::X8, PPC::X9, PPC::X10, PPC::X11,
+ PPC::X12, PPC::X13, PPC::X14, PPC::X15,
+ PPC::X16, PPC::X17, PPC::X18, PPC::X19,
+ PPC::X20, PPC::X21, PPC::X22, PPC::X23,
+ PPC::X24, PPC::X25, PPC::X26, PPC::X27,
+ PPC::X28, PPC::X29, PPC::X30, PPC::X31
+};
+static unsigned FRegs[32] = {
+ PPC::F0, PPC::F1, PPC::F2, PPC::F3,
+ PPC::F4, PPC::F5, PPC::F6, PPC::F7,
+ PPC::F8, PPC::F9, PPC::F10, PPC::F11,
+ PPC::F12, PPC::F13, PPC::F14, PPC::F15,
+ PPC::F16, PPC::F17, PPC::F18, PPC::F19,
+ PPC::F20, PPC::F21, PPC::F22, PPC::F23,
+ PPC::F24, PPC::F25, PPC::F26, PPC::F27,
+ PPC::F28, PPC::F29, PPC::F30, PPC::F31
+};
+static unsigned VRegs[32] = {
+ PPC::V0, PPC::V1, PPC::V2, PPC::V3,
+ PPC::V4, PPC::V5, PPC::V6, PPC::V7,
+ PPC::V8, PPC::V9, PPC::V10, PPC::V11,
+ PPC::V12, PPC::V13, PPC::V14, PPC::V15,
+ PPC::V16, PPC::V17, PPC::V18, PPC::V19,
+ PPC::V20, PPC::V21, PPC::V22, PPC::V23,
+ PPC::V24, PPC::V25, PPC::V26, PPC::V27,
+ PPC::V28, PPC::V29, PPC::V30, PPC::V31
+};
+static unsigned CRBITRegs[32] = {
+ PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN,
+ PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN,
+ PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN,
+ PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN,
+ PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN,
+ PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN,
+ PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN,
+ PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN
+};
+static unsigned CRRegs[8] = {
+ PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3,
+ PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7
+};
+
+struct PPCOperand;
+
+class PPCAsmParser : public MCTargetAsmParser {
+ MCSubtargetInfo &STI;
+ MCAsmParser &Parser;
+ bool IsPPC64;
+
+ MCAsmParser &getParser() const { return Parser; }
+ MCAsmLexer &getLexer() const { return Parser.getLexer(); }
+
+ void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
+ bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
+
+ bool isPPC64() const { return IsPPC64; }
+
+ bool MatchRegisterName(const AsmToken &Tok,
+ unsigned &RegNo, int64_t &IntVal);
+
+ virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
+
+ bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ bool ParseDirectiveWord(unsigned Size, SMLoc L);
+ bool ParseDirectiveTC(unsigned Size, SMLoc L);
+
+ bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ MCStreamer &Out, unsigned &ErrorInfo,
+ bool MatchingInlineAsm);
+
+ /// @name Auto-generated Match Functions
+ /// {
+
+#define GET_ASSEMBLER_HEADER
+#include "PPCGenAsmMatcher.inc"
+
+ /// }
+
+
+public:
+ PPCAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
+ : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
+ // Check for 64-bit vs. 32-bit pointer mode.
+ Triple TheTriple(STI.getTargetTriple());
+ IsPPC64 = TheTriple.getArch() == Triple::ppc64;
+ // Initialize the set of available features.
+ setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+ }
+
+ virtual bool ParseInstruction(ParseInstructionInfo &Info,
+ StringRef Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ virtual bool ParseDirective(AsmToken DirectiveID);
+};
+
+/// PPCOperand - Instances of this class represent a parsed PowerPC machine
+/// instruction.
+struct PPCOperand : public MCParsedAsmOperand {
+ enum KindTy {
+ Token,
+ Immediate,
+ Expression
+ } Kind;
+
+ SMLoc StartLoc, EndLoc;
+ bool IsPPC64;
+
+ struct TokOp {
+ const char *Data;
+ unsigned Length;
+ };
+
+ struct ImmOp {
+ int64_t Val;
+ };
+
+ struct ExprOp {
+ const MCExpr *Val;
+ };
+
+ union {
+ struct TokOp Tok;
+ struct ImmOp Imm;
+ struct ExprOp Expr;
+ };
+
+ PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
+public:
+ PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
+ Kind = o.Kind;
+ StartLoc = o.StartLoc;
+ EndLoc = o.EndLoc;
+ IsPPC64 = o.IsPPC64;
+ switch (Kind) {
+ case Token:
+ Tok = o.Tok;
+ break;
+ case Immediate:
+ Imm = o.Imm;
+ break;
+ case Expression:
+ Expr = o.Expr;
+ break;
+ }
+ }
+
+ /// getStartLoc - Get the location of the first token of this operand.
+ SMLoc getStartLoc() const { return StartLoc; }
+
+ /// getEndLoc - Get the location of the last token of this operand.
+ SMLoc getEndLoc() const { return EndLoc; }
+
+ /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
+ bool isPPC64() const { return IsPPC64; }
+
+ int64_t getImm() const {
+ assert(Kind == Immediate && "Invalid access!");
+ return Imm.Val;
+ }
+
+ const MCExpr *getExpr() const {
+ assert(Kind == Expression && "Invalid access!");
+ return Expr.Val;
+ }
+
+ unsigned getReg() const {
+ assert(isRegNumber() && "Invalid access!");
+ return (unsigned) Imm.Val;
+ }
+
+ unsigned getCCReg() const {
+ assert(isCCRegNumber() && "Invalid access!");
+ return (unsigned) Imm.Val;
+ }
+
+ unsigned getCRBitMask() const {
+ assert(isCRBitMask() && "Invalid access!");
+ return 7 - CountTrailingZeros_32(Imm.Val);
+ }
+
+ bool isToken() const { return Kind == Token; }
+ bool isImm() const { return Kind == Immediate || Kind == Expression; }
+ bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
+ bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
+ bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
+ bool isU16Imm() const { return Kind == Expression ||
+ (Kind == Immediate && isUInt<16>(getImm())); }
+ bool isS16Imm() const { return Kind == Expression ||
+ (Kind == Immediate && isInt<16>(getImm())); }
+ bool isS16ImmX4() const { return Kind == Expression ||
+ (Kind == Immediate && isInt<16>(getImm()) &&
+ (getImm() & 3) == 0); }
+ bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
+ bool isCCRegNumber() const { return Kind == Immediate &&
+ isUInt<3>(getImm()); }
+ bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
+ isPowerOf2_32(getImm()); }
+ bool isMem() const { return false; }
+ bool isReg() const { return false; }
+
+ void addRegOperands(MCInst &Inst, unsigned N) const {
+ llvm_unreachable("addRegOperands");
+ }
+
+ void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(RRegs[getReg()]));
+ }
+
+ void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(RRegsNoR0[getReg()]));
+ }
+
+ void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(XRegs[getReg()]));
+ }
+
+ void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(XRegsNoX0[getReg()]));
+ }
+
+ void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
+ if (isPPC64())
+ addRegG8RCOperands(Inst, N);
+ else
+ addRegGPRCOperands(Inst, N);
+ }
+
+ void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
+ if (isPPC64())
+ addRegG8RCNoX0Operands(Inst, N);
+ else
+ addRegGPRCNoR0Operands(Inst, N);
+ }
+
+ void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()]));
+ }
+
+ void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()]));
+ }
+
+ void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(VRegs[getReg()]));
+ }
+
+ void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(CRBITRegs[getReg()]));
+ }
+
+ void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(CRRegs[getCCReg()]));
+ }
+
+ void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(CRRegs[getCRBitMask()]));
+ }
+
+ void addImmOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ if (Kind == Immediate)
+ Inst.addOperand(MCOperand::CreateImm(getImm()));
+ else
+ Inst.addOperand(MCOperand::CreateExpr(getExpr()));
+ }
+
+ void addDispRIOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ if (Kind == Immediate)
+ Inst.addOperand(MCOperand::CreateImm(getImm()));
+ else
+ Inst.addOperand(MCOperand::CreateExpr(getExpr()));
+ }
+
+ void addDispRIXOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ if (Kind == Immediate)
+ Inst.addOperand(MCOperand::CreateImm(getImm() / 4));
+ else
+ Inst.addOperand(MCOperand::CreateExpr(getExpr()));
+ }
+
+ StringRef getToken() const {
+ assert(Kind == Token && "Invalid access!");
+ return StringRef(Tok.Data, Tok.Length);
+ }
+
+ virtual void print(raw_ostream &OS) const;
+
+ static PPCOperand *CreateToken(StringRef Str, SMLoc S, bool IsPPC64) {
+ PPCOperand *Op = new PPCOperand(Token);
+ Op->Tok.Data = Str.data();
+ Op->Tok.Length = Str.size();
+ Op->StartLoc = S;
+ Op->EndLoc = S;
+ Op->IsPPC64 = IsPPC64;
+ return Op;
+ }
+
+ static PPCOperand *CreateImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
+ PPCOperand *Op = new PPCOperand(Immediate);
+ Op->Imm.Val = Val;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ Op->IsPPC64 = IsPPC64;
+ return Op;
+ }
+
+ static PPCOperand *CreateExpr(const MCExpr *Val,
+ SMLoc S, SMLoc E, bool IsPPC64) {
+ PPCOperand *Op = new PPCOperand(Expression);
+ Op->Expr.Val = Val;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ Op->IsPPC64 = IsPPC64;
+ return Op;
+ }
+};
+
+} // end anonymous namespace.
+
+void PPCOperand::print(raw_ostream &OS) const {
+ switch (Kind) {
+ case Token:
+ OS << "'" << getToken() << "'";
+ break;
+ case Immediate:
+ OS << getImm();
+ break;
+ case Expression:
+ getExpr()->print(OS);
+ break;
+ }
+}
+
+
+bool PPCAsmParser::
+MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ MCStreamer &Out, unsigned &ErrorInfo,
+ bool MatchingInlineAsm) {
+ MCInst Inst;
+
+ switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
+ default: break;
+ case Match_Success:
+ Inst.setLoc(IDLoc);
+ Out.EmitInstruction(Inst);
+ return false;
+ case Match_MissingFeature:
+ return Error(IDLoc, "instruction use requires an option to be enabled");
+ case Match_MnemonicFail:
+ return Error(IDLoc, "unrecognized instruction mnemonic");
+ case Match_InvalidOperand: {
+ SMLoc ErrorLoc = IDLoc;
+ if (ErrorInfo != ~0U) {
+ if (ErrorInfo >= Operands.size())
+ return Error(IDLoc, "too few operands for instruction");
+
+ ErrorLoc = ((PPCOperand*)Operands[ErrorInfo])->getStartLoc();
+ if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
+ }
+
+ return Error(ErrorLoc, "invalid operand for instruction");
+ }
+ }
+
+ llvm_unreachable("Implement any new match types added!");
+}
+
+bool PPCAsmParser::
+MatchRegisterName(const AsmToken &Tok, unsigned &RegNo, int64_t &IntVal) {
+ if (Tok.is(AsmToken::Identifier)) {
+ StringRef Name = Tok.getString().lower();
+
+ if (Name == "lr") {
+ RegNo = isPPC64()? PPC::LR8 : PPC::LR;
+ IntVal = 8;
+ return false;
+ } else if (Name == "ctr") {
+ RegNo = isPPC64()? PPC::CTR8 : PPC::CTR;
+ IntVal = 9;
+ return false;
+ } else if (Name.startswith("r") &&
+ !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
+ RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal];
+ return false;
+ } else if (Name.startswith("f") &&
+ !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
+ RegNo = FRegs[IntVal];
+ return false;
+ } else if (Name.startswith("v") &&
+ !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
+ RegNo = VRegs[IntVal];
+ return false;
+ } else if (Name.startswith("cr") &&
+ !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
+ RegNo = CRRegs[IntVal];
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool PPCAsmParser::
+ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
+ const AsmToken &Tok = Parser.getTok();
+ StartLoc = Tok.getLoc();
+ EndLoc = Tok.getEndLoc();
+ RegNo = 0;
+ int64_t IntVal;
+
+ if (!MatchRegisterName(Tok, RegNo, IntVal)) {
+ Parser.Lex(); // Eat identifier token.
+ return false;
+ }
+
+ return Error(StartLoc, "invalid register name");
+}
+
+bool PPCAsmParser::
+ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ SMLoc S = Parser.getTok().getLoc();
+ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ const MCExpr *EVal;
+ PPCOperand *Op;
+
+ // Attempt to parse the next token as an immediate
+ switch (getLexer().getKind()) {
+ // Special handling for register names. These are interpreted
+ // as immediates corresponding to the register number.
+ case AsmToken::Percent:
+ Parser.Lex(); // Eat the '%'.
+ unsigned RegNo;
+ int64_t IntVal;
+ if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
+ Parser.Lex(); // Eat the identifier token.
+ Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64());
+ Operands.push_back(Op);
+ return false;
+ }
+ return Error(S, "invalid register name");
+
+ // All other expressions
+ case AsmToken::LParen:
+ case AsmToken::Plus:
+ case AsmToken::Minus:
+ case AsmToken::Integer:
+ case AsmToken::Identifier:
+ case AsmToken::Dot:
+ case AsmToken::Dollar:
+ if (!getParser().parseExpression(EVal))
+ break;
+ /* fall through */
+ default:
+ return Error(S, "unknown operand");
+ }
+
+ if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(EVal))
+ Op = PPCOperand::CreateImm(CE->getValue(), S, E, isPPC64());
+ else
+ Op = PPCOperand::CreateExpr(EVal, S, E, isPPC64());
+
+ // Push the parsed operand into the list of operands
+ Operands.push_back(Op);
+
+ // Check for D-form memory operands
+ if (getLexer().is(AsmToken::LParen)) {
+ Parser.Lex(); // Eat the '('.
+ S = Parser.getTok().getLoc();
+
+ int64_t IntVal;
+ switch (getLexer().getKind()) {
+ case AsmToken::Percent:
+ Parser.Lex(); // Eat the '%'.
+ unsigned RegNo;
+ if (MatchRegisterName(Parser.getTok(), RegNo, IntVal))
+ return Error(S, "invalid register name");
+ Parser.Lex(); // Eat the identifier token.
+ break;
+
+ case AsmToken::Integer:
+ if (getParser().parseAbsoluteExpression(IntVal) ||
+ IntVal < 0 || IntVal > 31)
+ return Error(S, "invalid register number");
+ break;
+
+ default:
+ return Error(S, "invalid memory operand");
+ }
+
+ if (getLexer().isNot(AsmToken::RParen))
+ return Error(Parser.getTok().getLoc(), "missing ')'");
+ E = Parser.getTok().getLoc();
+ Parser.Lex(); // Eat the ')'.
+
+ Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64());
+ Operands.push_back(Op);
+ }
+
+ return false;
+}
+
+/// Parse an instruction mnemonic followed by its operands.
+bool PPCAsmParser::
+ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ // The first operand is the token for the instruction name.
+ // If the instruction ends in a '.', we need to create a separate
+ // token for it, to match what TableGen is doing.
+ size_t Dot = Name.find('.');
+ StringRef Mnemonic = Name.slice(0, Dot);
+ Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
+ if (Dot != StringRef::npos) {
+ SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
+ StringRef DotStr = Name.slice(Dot, StringRef::npos);
+ Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
+ }
+
+ // If there are no more operands then finish
+ if (getLexer().is(AsmToken::EndOfStatement))
+ return false;
+
+ // Parse the first operand
+ if (ParseOperand(Operands))
+ return true;
+
+ while (getLexer().isNot(AsmToken::EndOfStatement) &&
+ getLexer().is(AsmToken::Comma)) {
+ // Consume the comma token
+ getLexer().Lex();
+
+ // Parse the next operand
+ if (ParseOperand(Operands))
+ return true;
+ }
+
+ return false;
+}
+
+/// ParseDirective parses the PPC specific directives
+bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
+ StringRef IDVal = DirectiveID.getIdentifier();
+ if (IDVal == ".word")
+ return ParseDirectiveWord(4, DirectiveID.getLoc());
+ if (IDVal == ".tc")
+ return ParseDirectiveTC(isPPC64()? 8 : 4, DirectiveID.getLoc());
+ return true;
+}
+
+/// ParseDirectiveWord
+/// ::= .word [ expression (, expression)* ]
+bool PPCAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ const MCExpr *Value;
+ if (getParser().parseExpression(Value))
+ return true;
+
+ getParser().getStreamer().EmitValue(Value, Size);
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return Error(L, "unexpected token in directive");
+ Parser.Lex();
+ }
+ }
+
+ Parser.Lex();
+ return false;
+}
+
+/// ParseDirectiveTC
+/// ::= .tc [ symbol (, expression)* ]
+bool PPCAsmParser::ParseDirectiveTC(unsigned Size, SMLoc L) {
+ // Skip TC symbol, which is only used with XCOFF.
+ while (getLexer().isNot(AsmToken::EndOfStatement)
+ && getLexer().isNot(AsmToken::Comma))
+ Parser.Lex();
+ if (getLexer().isNot(AsmToken::Comma))
+ return Error(L, "unexpected token in directive");
+ Parser.Lex();
+
+ // Align to word size.
+ getParser().getStreamer().EmitValueToAlignment(Size);
+
+ // Emit expressions.
+ return ParseDirectiveWord(Size, L);
+}
+
+/// Force static initialization.
+extern "C" void LLVMInitializePowerPCAsmParser() {
+ RegisterMCAsmParser<PPCAsmParser> A(ThePPC32Target);
+ RegisterMCAsmParser<PPCAsmParser> B(ThePPC64Target);
+}
+
+#define GET_REGISTER_MATCHER
+#define GET_MATCHER_IMPLEMENTATION
+#include "PPCGenAsmMatcher.inc"
diff --git a/llvm/lib/Target/PowerPC/CMakeLists.txt b/llvm/lib/Target/PowerPC/CMakeLists.txt
index 6036428fad9..71803cdac9c 100644
--- a/llvm/lib/Target/PowerPC/CMakeLists.txt
+++ b/llvm/lib/Target/PowerPC/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LLVM_TARGET_DEFINITIONS PPC.td)
tablegen(LLVM PPCGenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM PPCGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM PPCGenCodeEmitter.inc -gen-emitter)
tablegen(LLVM PPCGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
tablegen(LLVM PPCGenRegisterInfo.inc -gen-register-info)
@@ -32,6 +33,7 @@ add_llvm_target(PowerPCCodeGen
add_dependencies(LLVMPowerPCCodeGen intrinsics_gen)
+add_subdirectory(AsmParser)
add_subdirectory(InstPrinter)
add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)
diff --git a/llvm/lib/Target/PowerPC/LLVMBuild.txt b/llvm/lib/Target/PowerPC/LLVMBuild.txt
index 95fac5471ec..7b3e843507a 100644
--- a/llvm/lib/Target/PowerPC/LLVMBuild.txt
+++ b/llvm/lib/Target/PowerPC/LLVMBuild.txt
@@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = InstPrinter MCTargetDesc TargetInfo
+subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
[component_0]
type = TargetGroup
diff --git a/llvm/lib/Target/PowerPC/Makefile b/llvm/lib/Target/PowerPC/Makefile
index 1617b26ca4a..6666694ecc7 100644
--- a/llvm/lib/Target/PowerPC/Makefile
+++ b/llvm/lib/Target/PowerPC/Makefile
@@ -12,12 +12,12 @@ LIBRARYNAME = LLVMPowerPCCodeGen
TARGET = PPC
# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = PPCGenRegisterInfo.inc \
+BUILT_SOURCES = PPCGenRegisterInfo.inc PPCGenAsmMatcher.inc \
PPCGenAsmWriter.inc PPCGenCodeEmitter.inc \
PPCGenInstrInfo.inc PPCGenDAGISel.inc \
PPCGenSubtargetInfo.inc PPCGenCallingConv.inc \
PPCGenMCCodeEmitter.inc
-DIRS = InstPrinter TargetInfo MCTargetDesc
+DIRS = AsmParser InstPrinter TargetInfo MCTargetDesc
include $(LEVEL)/Makefile.common
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td
index 649ffc1abea..eb73c676ad7 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -268,9 +268,14 @@ def PPCAsmWriter : AsmWriter {
bit isMCAsmWriter = 1;
}
+def PPCAsmParser : AsmParser {
+ let ShouldEmitMatchRegisterName = 0;
+}
+
def PPC : Target {
// Information about the instructions.
let InstructionSet = PPCInstrInfo;
let AssemblyWriters = [PPCAsmWriter];
+ let AssemblyParsers = [PPCAsmParser];
}
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index e5d0b913409..bff4c230ce6 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -17,17 +17,21 @@
//
def s16imm64 : Operand<i64> {
let PrintMethod = "printS16ImmOperand";
+ let ParserMatchClass = PPCS16ImmAsmOperand;
}
def u16imm64 : Operand<i64> {
let PrintMethod = "printU16ImmOperand";
+ let ParserMatchClass = PPCU16ImmAsmOperand;
}
def symbolHi64 : Operand<i64> {
let PrintMethod = "printSymbolHi";
let EncoderMethod = "getHA16Encoding";
+ let ParserMatchClass = PPCS16ImmAsmOperand;
}
def symbolLo64 : Operand<i64> {
let PrintMethod = "printSymbolLo";
let EncoderMethod = "getLO16Encoding";
+ let ParserMatchClass = PPCS16ImmAsmOperand;
}
def tocentry : Operand<iPTR> {
let MIOperandInfo = (ops i64imm:$imm);
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 7d3540e1583..d3d2ce9bc6c 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -342,30 +342,101 @@ class NoEncode<string E> {
// all their register operands.
// For this purpose, we define one RegisterOperand for each RegisterClass,
// using the same name as the class, just in lower case.
-def gprc : RegisterOperand<GPRC>;
-def g8rc : RegisterOperand<G8RC>;
-def gprc_nor0 : RegisterOperand<GPRC_NOR0>;
-def g8rc_nox0 : RegisterOperand<G8RC_NOX0>;
-def f8rc : RegisterOperand<F8RC>;
-def f4rc : RegisterOperand<F4RC>;
-def vrrc : RegisterOperand<VRRC>;
-def crbitrc : RegisterOperand<CRBITRC>;
-def crrc : RegisterOperand<CRRC>;
+def PPCRegGPRCAsmOperand : AsmOperandClass {
+ let Name = "RegGPRC"; let PredicateMethod = "isRegNumber";
+}
+def gprc : RegisterOperand<GPRC> {
+ let ParserMatchClass = PPCRegGPRCAsmOperand;
+}
+def PPCRegG8RCAsmOperand : AsmOperandClass {
+ let Name = "RegG8RC"; let PredicateMethod = "isRegNumber";
+}
+def g8rc : RegisterOperand<G8RC> {
+ let ParserMatchClass = PPCRegG8RCAsmOperand;
+}
+def PPCRegGPRCNoR0AsmOperand : AsmOperandClass {
+ let Name = "RegGPRCNoR0"; let PredicateMethod = "isRegNumber";
+}
+def gprc_nor0 : RegisterOperand<GPRC_NOR0> {
+ let ParserMatchClass = PPCRegGPRCNoR0AsmOperand;
+}
+def PPCRegG8RCNoX0AsmOperand : AsmOperandClass {
+ let Name = "RegG8RCNoX0"; let PredicateMethod = "isRegNumber";
+}
+def g8rc_nox0 : RegisterOperand<G8RC_NOX0> {
+ let ParserMatchClass = PPCRegG8RCNoX0AsmOperand;
+}
+def PPCRegF8RCAsmOperand : AsmOperandClass {
+ let Name = "RegF8RC"; let PredicateMethod = "isRegNumber";
+}
+def f8rc : RegisterOperand<F8RC> {
+ let ParserMatchClass = PPCRegF8RCAsmOperand;
+}
+def PPCRegF4RCAsmOperand : AsmOperandClass {
+ let Name = "RegF4RC"; let PredicateMethod = "isRegNumber";
+}
+def f4rc : RegisterOperand<F4RC> {
+ let ParserMatchClass = PPCRegF4RCAsmOperand;
+}
+def PPCRegVRRCAsmOperand : AsmOperandClass {
+ let Name = "RegVRRC"; let PredicateMethod = "isRegNumber";
+}
+def vrrc : RegisterOperand<VRRC> {
+ let ParserMatchClass = PPCRegVRRCAsmOperand;
+}
+def PPCRegCRBITRCAsmOperand : AsmOperandClass {
+ let Name = "RegCRBITRC"; let PredicateMethod = "isRegNumber";
+}
+def crbitrc : RegisterOperand<CRBITRC> {
+ let ParserMatchClass = PPCRegCRBITRCAsmOperand;
+}
+def PPCRegCRRCAsmOperand : AsmOperandClass {
+ let Name = "RegCRRC"; let PredicateMethod = "isCCRegNumber";
+}
+def crrc : RegisterOperand<CRRC> {
+ let ParserMatchClass = PPCRegCRRCAsmOperand;
+}
+
+def PPCS5ImmAsmOperand : AsmOperandClass {
+ let Name = "S5Imm"; let PredicateMethod = "isS5Imm";
+ let RenderMethod = "addImmOperands";
+}
def s5imm : Operand<i32> {
let PrintMethod = "printS5ImmOperand";
+ let ParserMatchClass = PPCS5ImmAsmOperand;
+}
+def PPCU5ImmAsmOperand : AsmOperandClass {
+ let Name = "U5Imm"; let PredicateMethod = "isU5Imm";
+ let RenderMethod = "addImmOperands";
}
def u5imm : Operand<i32> {
let PrintMethod = "printU5ImmOperand";
+ let ParserMatchClass = PPCU5ImmAsmOperand;
+}
+def PPCU6ImmAsmOperand : AsmOperandClass {
+ let Name = "U6Imm"; let PredicateMethod = "isU6Imm";
+ let RenderMethod = "addImmOperands";
}
def u6imm : Operand<i32> {
let PrintMethod = "printU6ImmOperand";
+ let ParserMatchClass = PPCU6ImmAsmOperand;
+}
+def PPCS16ImmAsmOperand : AsmOperandClass {
+ let Name = "S16Imm"; let PredicateMethod = "isS16Imm";
+ let RenderMethod = "addImmOperands";
}
def s16imm : Operand<i32> {
let PrintMethod = "printS16ImmOperand";
+ let ParserMatchClass = PPCS16ImmAsmOperand;
+}
+def PPCU16ImmAsmOperand : AsmOperandClass {
+ let Name = "U16Imm"; let PredicateMethod = "isU16Imm";
+ let RenderMethod = "addImmOperands";
}
def u16imm : Operand<i32> {
let PrintMethod = "printU16ImmOperand";
+ let ParserMatchClass = PPCU16ImmAsmOperand;
}
def directbrtarget : Operand<OtherVT> {
let PrintMethod = "printBranchOperand";
@@ -384,21 +455,49 @@ def aaddr : Operand<iPTR> {
def symbolHi: Operand<i32> {
let PrintMethod = "printSymbolHi";
let EncoderMethod = "getHA16Encoding";
+ let ParserMatchClass = PPCS16ImmAsmOperand;
}
def symbolLo: Operand<i32> {
let PrintMethod = "printSymbolLo";
let EncoderMethod = "getLO16Encoding";
+ let ParserMatchClass = PPCS16ImmAsmOperand;
+}
+def PPCCRBitMaskOperand : AsmOperandClass {
+ let Name = "CRBitMask"; let PredicateMethod = "isCRBitMask";
}
def crbitm: Operand<i8> {
let PrintMethod = "printcrbitm";
let EncoderMethod = "get_crbitm_encoding";
+ let ParserMatchClass = PPCCRBitMaskOperand;
}
// Address operands
// A version of ptr_rc which excludes R0 (or X0 in 64-bit mode).
-def ptr_rc_nor0 : PointerLikeRegClass<1>;
+def PPCRegGxRCNoR0Operand : AsmOperandClass {
+ let Name = "RegGxRCNoR0"; let PredicateMethod = "isRegNumber";
+}
+def ptr_rc_nor0 : Operand<iPTR>, PointerLikeRegClass<1> {
+ let ParserMatchClass = PPCRegGxRCNoR0Operand;
+}
+// A version of ptr_rc usable with the asm parser.
+def PPCRegGxRCOperand : AsmOperandClass {
+ let Name = "RegGxRC"; let PredicateMethod = "isRegNumber";
+}
+def ptr_rc_idx : Operand<iPTR>, PointerLikeRegClass<0> {
+ let ParserMatchClass = PPCRegGxRCOperand;
+}
-def dispRI : Operand<iPTR>;
-def dispRIX : Operand<iPTR>;
+def PPCDispRIOperand : AsmOperandClass {
+ let Name = "DispRI"; let PredicateMethod = "isS16Imm";
+}
+def dispRI : Operand<iPTR> {
+ let ParserMatchClass = PPCDispRIOperand;
+}
+def PPCDispRIXOperand : AsmOperandClass {
+ let Name = "DispRIX"; let PredicateMethod = "isS16ImmX4";
+}
+def dispRIX : Operand<iPTR> {
+ let ParserMatchClass = PPCDispRIXOperand;
+}
def memri : Operand<iPTR> {
let PrintMethod = "printMemRegImm";
@@ -407,7 +506,7 @@ def memri : Operand<iPTR> {
}
def memrr : Operand<iPTR> {
let PrintMethod = "printMemRegReg";
- let MIOperandInfo = (ops ptr_rc_nor0:$ptrreg, ptr_rc:$offreg);
+ let MIOperandInfo = (ops ptr_rc_nor0:$ptrreg, ptr_rc_idx:$offreg);
}
def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
let PrintMethod = "printMemRegImmShifted";
diff --git a/llvm/test/MC/PowerPC/ppc64-encoding-fp.s b/llvm/test/MC/PowerPC/ppc64-encoding-fp.s
new file mode 100644
index 00000000000..ae0e2866a26
--- /dev/null
+++ b/llvm/test/MC/PowerPC/ppc64-encoding-fp.s
@@ -0,0 +1,263 @@
+
+# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck %s
+
+# Floating-point facility
+
+# Floating-point load instructions
+
+# CHECK: lfs 2, 128(4) # encoding: [0xc0,0x44,0x00,0x80]
+ lfs 2, 128(4)
+# CHECK: lfsx 2, 3, 4 # encoding: [0x7c,0x43,0x24,0x2e]
+ lfsx 2, 3, 4
+# CHECK: lfsu 2, 128(4) # encoding: [0xc4,0x44,0x00,0x80]
+ lfsu 2, 128(4)
+# CHECK: lfsux 2, 3, 4 # encoding: [0x7c,0x43,0x24,0x6e]
+ lfsux 2, 3, 4
+# CHECK: lfd 2, 128(4) # encoding: [0xc8,0x44,0x00,0x80]
+ lfd 2, 128(4)
+# CHECK: lfdx 2, 3, 4 # encoding: [0x7c,0x43,0x24,0xae]
+ lfdx 2, 3, 4
+# CHECK: lfdu 2, 128(4) # encoding: [0xcc,0x44,0x00,0x80]
+ lfdu 2, 128(4)
+# CHECK: lfdux 2, 3, 4 # encoding: [0x7c,0x43,0x24,0xee]
+ lfdux 2, 3, 4
+# CHECK: lfiwax 2, 3, 4 # encoding: [0x7c,0x43,0x26,0xae]
+ lfiwax 2, 3, 4
+# CHECK: lfiwzx 2, 3, 4 # encoding: [0x7c,0x43,0x26,0xee]
+ lfiwzx 2, 3, 4
+
+# Floating-point store instructions
+
+# CHECK: stfs 2, 128(4) # encoding: [0xd0,0x44,0x00,0x80]
+ stfs 2, 128(4)
+# CHECK: stfsx 2, 3, 4 # encoding: [0x7c,0x43,0x25,0x2e]
+ stfsx 2, 3, 4
+# CHECK: stfsu 2, 128(4) # encoding: [0xd4,0x44,0x00,0x80]
+ stfsu 2, 128(4)
+# CHECK: stfsux 2, 3, 4 # encoding: [0x7c,0x43,0x25,0x6e]
+ stfsux 2, 3, 4
+# CHECK: stfd 2, 128(4) # encoding: [0xd8,0x44,0x00,0x80]
+ stfd 2, 128(4)
+# CHECK: stfdx 2, 3, 4 # encoding: [0x7c,0x43,0x25,0xae]
+ stfdx 2, 3, 4
+# CHECK: stfdu 2, 128(4) # encoding: [0xdc,0x44,0x00,0x80]
+ stfdu 2, 128(4)
+# CHECK: stfdux 2, 3, 4 # encoding: [0x7c,0x43,0x25,0xee]
+ stfdux 2, 3, 4
+# CHECK: stfiwx 2, 3, 4 # encoding: [0x7c,0x43,0x27,0xae]
+ stfiwx 2, 3, 4
+
+# Floating-point move instructions
+
+# CHECK: fmr 2, 3 # encoding: [0xfc,0x40,0x18,0x90]
+ fmr 2, 3
+# CHECK: fmr. 2, 3 # encoding: [0xfc,0x40,0x18,0x91]
+ fmr. 2, 3
+# CHECK: fneg 2, 3 # encoding: [0xfc,0x40,0x18,0x50]
+ fneg 2, 3
+# CHECK: fneg. 2, 3 # encoding: [0xfc,0x40,0x18,0x51]
+ fneg. 2, 3
+# CHECK: fabs 2, 3 # encoding: [0xfc,0x40,0x1a,0x10]
+ fabs 2, 3
+# CHECK: fabs. 2, 3 # encoding: [0xfc,0x40,0x1a,0x11]
+ fabs. 2, 3
+# CHECK: fnabs 2, 3 # encoding: [0xfc,0x40,0x19,0x10]
+ fnabs 2, 3
+# CHECK: fnabs. 2, 3 # encoding: [0xfc,0x40,0x19,0x11]
+ fnabs. 2, 3
+# FIXME: fcpsgn 2, 3
+# FIXME: fcpsgn. 2, 3
+
+# Floating-point arithmetic instructions
+
+# CHECK: fadd 2, 3, 4 # encoding: [0xfc,0x43,0x20,0x2a]
+ fadd 2, 3, 4
+# CHECK: fadd. 2, 3, 4 # encoding: [0xfc,0x43,0x20,0x2b]
+ fadd. 2, 3, 4
+# CHECK: fadds 2, 3, 4 # encoding: [0xec,0x43,0x20,0x2a]
+ fadds 2, 3, 4
+# CHECK: fadds. 2, 3, 4 # encoding: [0xec,0x43,0x20,0x2b]
+ fadds. 2, 3, 4
+# CHECK: fsub 2, 3, 4 # encoding: [0xfc,0x43,0x20,0x28]
+ fsub 2, 3, 4
+# CHECK: fsub. 2, 3, 4 # encoding: [0xfc,0x43,0x20,0x29]
+ fsub. 2, 3, 4
+# CHECK: fsubs 2, 3, 4 # encoding: [0xec,0x43,0x20,0x28]
+ fsubs 2, 3, 4
+# CHECK: fsubs. 2, 3, 4 # encoding: [0xec,0x43,0x20,0x29]
+ fsubs. 2, 3, 4
+
+# CHECK: fmul 2, 3, 4 # encoding: [0xfc,0x43,0x01,0x32]
+ fmul 2, 3, 4
+# CHECK: fmul. 2, 3, 4 # encoding: [0xfc,0x43,0x01,0x33]
+ fmul. 2, 3, 4
+# CHECK: fmuls 2, 3, 4 # encoding: [0xec,0x43,0x01,0x32]
+ fmuls 2, 3, 4
+# CHECK: fmuls. 2, 3, 4 # encoding: [0xec,0x43,0x01,0x33]
+ fmuls. 2, 3, 4
+# CHECK: fdiv 2, 3, 4 # encoding: [0xfc,0x43,0x20,0x24]
+ fdiv 2, 3, 4
+# CHECK: fdiv. 2, 3, 4 # encoding: [0xfc,0x43,0x20,0x25]
+ fdiv. 2, 3, 4
+# CHECK: fdivs 2, 3, 4 # encoding: [0xec,0x43,0x20,0x24]
+ fdivs 2, 3, 4
+# CHECK: fdivs. 2, 3, 4 # encoding: [0xec,0x43,0x20,0x25]
+ fdivs. 2, 3, 4
+# CHECK: fsqrt 2, 3 # encoding: [0xfc,0x40,0x18,0x2c]
+ fsqrt 2, 3
+# CHECK: fsqrt. 2, 3 # encoding: [0xfc,0x40,0x18,0x2d]
+ fsqrt. 2, 3
+# CHECK: fsqrts 2, 3 # encoding: [0xec,0x40,0x18,0x2c]
+ fsqrts 2, 3
+# CHECK: fsqrts. 2, 3 # encoding: [0xec,0x40,0x18,0x2d]
+ fsqrts. 2, 3
+
+# CHECK: fre 2, 3 # encoding: [0xfc,0x40,0x18,0x30]
+ fre 2, 3
+# CHECK: fre. 2, 3 # encoding: [0xfc,0x40,0x18,0x31]
+ fre. 2, 3
+# CHECK: fres 2, 3 # encoding: [0xec,0x40,0x18,0x30]
+ fres 2, 3
+# CHECK: fres. 2, 3 # encoding: [0xec,0x40,0x18,0x31]
+ fres. 2, 3
+# CHECK: frsqrte 2, 3 # encoding: [0xfc,0x40,0x18,0x34]
+ frsqrte 2, 3
+# CHECK: frsqrte. 2, 3 # encoding: [0xfc,0x40,0x18,0x35]
+ frsqrte. 2, 3
+# CHECK: frsqrtes 2, 3 # encoding: [0xec,0x40,0x18,0x34]
+ frsqrtes 2, 3
+# CHECK: frsqrtes. 2, 3 # encoding: [0xec,0x40,0x18,0x35]
+ frsqrtes. 2, 3
+# FIXME: ftdiv 2, 3, 4
+# FIXME: ftsqrt 2, 3, 4
+
+# CHECK: fmadd 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x3a]
+ fmadd 2, 3, 4, 5
+# CHECK: fmadd. 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x3b]
+ fmadd. 2, 3, 4, 5
+# CHECK: fmadds 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x3a]
+ fmadds 2, 3, 4, 5
+# CHECK: fmadds. 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x3b]
+ fmadds. 2, 3, 4, 5
+# CHECK: fmsub 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x38]
+ fmsub 2, 3, 4, 5
+# CHECK: fmsub. 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x39]
+ fmsub. 2, 3, 4, 5
+# CHECK: fmsubs 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x38]
+ fmsubs 2, 3, 4, 5
+# CHECK: fmsubs. 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x39]
+ fmsubs. 2, 3, 4, 5
+# CHECK: fnmadd 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x3e]
+ fnmadd 2, 3, 4, 5
+# CHECK: fnmadd. 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x3f]
+ fnmadd. 2, 3, 4, 5
+# CHECK: fnmadds 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x3e]
+ fnmadds 2, 3, 4, 5
+# CHECK: fnmadds. 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x3f]
+ fnmadds. 2, 3, 4, 5
+# CHECK: fnmsub 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x3c]
+ fnmsub 2, 3, 4, 5
+# CHECK: fnmsub. 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x3d]
+ fnmsub. 2, 3, 4, 5
+# CHECK: fnmsubs 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x3c]
+ fnmsubs 2, 3, 4, 5
+# CHECK: fnmsubs. 2, 3, 4, 5 # encoding: [0xec,0x43,0x29,0x3d]
+ fnmsubs. 2, 3, 4, 5
+
+# Floating-point rounding and conversion instructions
+
+# CHECK: frsp 2, 3 # encoding: [0xfc,0x40,0x18,0x18]
+ frsp 2, 3
+# CHECK: frsp. 2, 3 # encoding: [0xfc,0x40,0x18,0x19]
+ frsp. 2, 3
+
+# FIXME: fctid 2, 3
+# FIXME: fctid. 2, 3
+# CHECK: fctidz 2, 3 # encoding: [0xfc,0x40,0x1e,0x5e]
+ fctidz 2, 3
+# CHECK: fctidz. 2, 3 # encoding: [0xfc,0x40,0x1e,0x5f]
+ fctidz. 2, 3
+# FIXME: fctidu 2, 3
+# FIXME: fctidu. 2, 3
+# CHECK: fctiduz 2, 3 # encoding: [0xfc,0x40,0x1f,0x5e]
+ fctiduz 2, 3
+# CHECK: fctiduz. 2, 3 # encoding: [0xfc,0x40,0x1f,0x5f]
+ fctiduz. 2, 3
+# FIXME: fctiw 2, 3
+# FIXME: fctiw. 2, 3
+# CHECK: fctiwz 2, 3 # encoding: [0xfc,0x40,0x18,0x1e]
+ fctiwz 2, 3
+# CHECK: fctiwz. 2, 3 # encoding: [0xfc,0x40,0x18,0x1f]
+ fctiwz. 2, 3
+# FIXME: fctiwu 2, 3
+# FIXME: fctiwu. 2, 3
+# CHECK: fctiwuz 2, 3 # encoding: [0xfc,0x40,0x19,0x1e]
+ fctiwuz 2, 3
+# CHECK: fctiwuz. 2, 3 # encoding: [0xfc,0x40,0x19,0x1f]
+ fctiwuz. 2, 3
+# CHECK: fcfid 2, 3 # encoding: [0xfc,0x40,0x1e,0x9c]
+ fcfid 2, 3
+# CHECK: fcfid. 2, 3 # encoding: [0xfc,0x40,0x1e,0x9d]
+ fcfid. 2, 3
+# CHECK: fcfidu 2, 3 # encoding: [0xfc,0x40,0x1f,0x9c]
+ fcfidu 2, 3
+# CHECK: fcfidu. 2, 3 # encoding: [0xfc,0x40,0x1f,0x9d]
+ fcfidu. 2, 3
+# CHECK: fcfids 2, 3 # encoding: [0xec,0x40,0x1e,0x9c]
+ fcfids 2, 3
+# CHECK: fcfids. 2, 3 # encoding: [0xec,0x40,0x1e,0x9d]
+ fcfids. 2, 3
+# CHECK: fcfidus 2, 3 # encoding: [0xec,0x40,0x1f,0x9c]
+ fcfidus 2, 3
+# CHECK: fcfidus. 2, 3 # encoding: [0xec,0x40,0x1f,0x9d]
+ fcfidus. 2, 3
+# CHECK: frin 2, 3 # encoding: [0xfc,0x40,0x1b,0x10]
+ frin 2, 3
+# CHECK: frin. 2, 3 # encoding: [0xfc,0x40,0x1b,0x11]
+ frin. 2, 3
+# CHECK: frip 2, 3 # encoding: [0xfc,0x40,0x1b,0x90]
+ frip 2, 3
+# CHECK: frip. 2, 3 # encoding: [0xfc,0x40,0x1b,0x91]
+ frip. 2, 3
+# CHECK: friz 2, 3 # encoding: [0xfc,0x40,0x1b,0x50]
+ friz 2, 3
+# CHECK: friz. 2, 3 # encoding: [0xfc,0x40,0x1b,0x51]
+ friz. 2, 3
+# CHECK: frim 2, 3 # encoding: [0xfc,0x40,0x1b,0xd0]
+ frim 2, 3
+# CHECK: frim. 2, 3 # encoding: [0xfc,0x40,0x1b,0xd1]
+ frim. 2, 3
+
+# Floating-point compare instructions
+
+# CHECK: fcmpu 2, 3, 4 # encoding: [0xfd,0x03,0x20,0x00]
+ fcmpu 2, 3, 4
+# FIXME: fcmpo 2, 3, 4
+
+# Floating-point select instruction
+
+# CHECK: fsel 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x2e]
+ fsel 2, 3, 4, 5
+# CHECK: fsel. 2, 3, 4, 5 # encoding: [0xfc,0x43,0x29,0x2f]
+ fsel. 2, 3, 4, 5
+
+# Floating-point status and control register instructions
+
+# CHECK: mffs 2 # encoding: [0xfc,0x40,0x04,0x8e]
+ mffs 2
+# FIXME: mffs. 2
+
+# FIXME: mcrfs 2, 3
+
+# FIXME: mtfsfi 2, 3, 1
+# FIXME: mtfsfi. 2, 3, 1
+# FIXME: mtfsf 2, 3, 1, 1
+# FIXME: mtfsf. 2, 3, 1, 1
+
+# CHECK: mtfsb0 31 # encoding: [0xff,0xe0,0x00,0x8c]
+ mtfsb0 31
+# FIXME: mtfsb0. 31
+# CHECK: mtfsb1 31 # encoding: [0xff,0xe0,0x00,0x4c]
+ mtfsb1 31
+# FIXME: mtfsb1. 31
+
diff --git a/llvm/test/MC/PowerPC/ppc64-encoding-vmx.s b/llvm/test/MC/PowerPC/ppc64-encoding-vmx.s
new file mode 100644
index 00000000000..0154076390b
--- /dev/null
+++ b/llvm/test/MC/PowerPC/ppc64-encoding-vmx.s
@@ -0,0 +1,384 @@
+
+# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck %s
+
+# Vector facility
+
+# Vector storage access instructions
+
+# CHECK: lvebx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x0e]
+ lvebx 2, 3, 4
+# CHECK: lvehx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x4e]
+ lvehx 2, 3, 4
+# CHECK: lvewx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x8e]
+ lvewx 2, 3, 4
+# CHECK: lvx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0xce]
+ lvx 2, 3, 4
+# CHECK: lvxl 2, 3, 4 # encoding: [0x7c,0x43,0x22,0xce]
+ lvxl 2, 3, 4
+# CHECK: stvebx 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x0e]
+ stvebx 2, 3, 4
+# CHECK: stvehx 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x4e]
+ stvehx 2, 3, 4
+# CHECK: stvewx 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x8e]
+ stvewx 2, 3, 4
+# CHECK: stvx 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xce]
+ stvx 2, 3, 4
+# CHECK: stvxl 2, 3, 4 # encoding: [0x7c,0x43,0x23,0xce]
+ stvxl 2, 3, 4
+# CHECK: lvsl 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x0c]
+ lvsl 2, 3, 4
+# CHECK: lvsr 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x4c]
+ lvsr 2, 3, 4
+
+# Vector permute and formatting instructions
+
+# CHECK: vpkpx 2, 3, 4 # encoding: [0x10,0x43,0x23,0x0e]
+ vpkpx 2, 3, 4
+# CHECK: vpkshss 2, 3, 4 # encoding: [0x10,0x43,0x21,0x8e]
+ vpkshss 2, 3, 4
+# CHECK: vpkshus 2, 3, 4 # encoding: [0x10,0x43,0x21,0x0e]
+ vpkshus 2, 3, 4
+# CHECK: vpkswss 2, 3, 4 # encoding: [0x10,0x43,0x21,0xce]
+ vpkswss 2, 3, 4
+# CHECK: vpkswus 2, 3, 4 # encoding: [0x10,0x43,0x21,0x4e]
+ vpkswus 2, 3, 4
+# CHECK: vpkuhum 2, 3, 4 # encoding: [0x10,0x43,0x20,0x0e]
+ vpkuhum 2, 3, 4
+# CHECK: vpkuhus 2, 3, 4 # encoding: [0x10,0x43,0x20,0x8e]
+ vpkuhus 2, 3, 4
+# CHECK: vpkuwum 2, 3, 4 # encoding: [0x10,0x43,0x20,0x4e]
+ vpkuwum 2, 3, 4
+# CHECK: vpkuwus 2, 3, 4 # encoding: [0x10,0x43,0x20,0xce]
+ vpkuwus 2, 3, 4
+
+# CHECK: vupkhpx 2, 3 # encoding: [0x10,0x40,0x1b,0x4e]
+ vupkhpx 2, 3
+# CHECK: vupkhsb 2, 3 # encoding: [0x10,0x40,0x1a,0x0e]
+ vupkhsb 2, 3
+# CHECK: vupkhsh 2, 3 # encoding: [0x10,0x40,0x1a,0x4e]
+ vupkhsh 2, 3
+# CHECK: vupklpx 2, 3 # encoding: [0x10,0x40,0x1b,0xce]
+ vupklpx 2, 3
+# CHECK: vupklsb 2, 3 # encoding: [0x10,0x40,0x1a,0x8e]
+ vupklsb 2, 3
+# CHECK: vupklsh 2, 3 # encoding: [0x10,0x40,0x1a,0xce]
+ vupklsh 2, 3
+
+# CHECK: vmrghb 2, 3, 4 # encoding: [0x10,0x43,0x20,0x0c]
+ vmrghb 2, 3, 4
+# CHECK: vmrghh 2, 3, 4 # encoding: [0x10,0x43,0x20,0x4c]
+ vmrghh 2, 3, 4
+# CHECK: vmrghw 2, 3, 4 # encoding: [0x10,0x43,0x20,0x8c]
+ vmrghw 2, 3, 4
+# CHECK: vmrglb 2, 3, 4 # encoding: [0x10,0x43,0x21,0x0c]
+ vmrglb 2, 3, 4
+# CHECK: vmrglh 2, 3, 4 # encoding: [0x10,0x43,0x21,0x4c]
+ vmrglh 2, 3, 4
+# CHECK: vmrglw 2, 3, 4 # encoding: [0x10,0x43,0x21,0x8c]
+ vmrglw 2, 3, 4
+
+# CHECK: vspltb 2, 3, 1 # encoding: [0x10,0x41,0x1a,0x0c]
+ vspltb 2, 3, 1
+# CHECK: vsplth 2, 3, 1 # encoding: [0x10,0x41,0x1a,0x4c]
+ vsplth 2, 3, 1
+# CHECK: vspltw 2, 3, 1 # encoding: [0x10,0x41,0x1a,0x8c]
+ vspltw 2, 3, 1
+# CHECK: vspltisb 2, 3 # encoding: [0x10,0x43,0x03,0x0c]
+ vspltisb 2, 3
+# CHECK: vspltish 2, 3 # encoding: [0x10,0x43,0x03,0x4c]
+ vspltish 2, 3
+# CHECK: vspltisw 2, 3 # encoding: [0x10,0x43,0x03,0x8c]
+ vspltisw 2, 3
+
+# CHECK: vperm 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x6b]
+ vperm 2, 3, 4, 5
+# CHECK: vsel 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x6a]
+ vsel 2, 3, 4, 5
+
+# CHECK: vsl 2, 3, 4 # encoding: [0x10,0x43,0x21,0xc4]
+ vsl 2, 3, 4
+# CHECK: vsldoi 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x6c]
+ vsldoi 2, 3, 4, 5
+# CHECK: vslo 2, 3, 4 # encoding: [0x10,0x43,0x24,0x0c]
+ vslo 2, 3, 4
+# CHECK: vsr 2, 3, 4 # encoding: [0x10,0x43,0x22,0xc4]
+ vsr 2, 3, 4
+# CHECK: vsro 2, 3, 4 # encoding: [0x10,0x43,0x24,0x4c]
+ vsro 2, 3, 4
+
+# Vector integer arithmetic instructions
+
+# CHECK: vaddcuw 2, 3, 4 # encoding: [0x10,0x43,0x21,0x80]
+ vaddcuw 2, 3, 4
+# CHECK: vaddsbs 2, 3, 4 # encoding: [0x10,0x43,0x23,0x00]
+ vaddsbs 2, 3, 4
+# CHECK: vaddshs 2, 3, 4 # encoding: [0x10,0x43,0x23,0x40]
+ vaddshs 2, 3, 4
+# CHECK: vaddsws 2, 3, 4 # encoding: [0x10,0x43,0x23,0x80]
+ vaddsws 2, 3, 4
+# CHECK: vaddubm 2, 3, 4 # encoding: [0x10,0x43,0x20,0x00]
+ vaddubm 2, 3, 4
+# CHECK: vadduhm 2, 3, 4 # encoding: [0x10,0x43,0x20,0x40]
+ vadduhm 2, 3, 4
+# CHECK: vadduwm 2, 3, 4 # encoding: [0x10,0x43,0x20,0x80]
+ vadduwm 2, 3, 4
+# CHECK: vaddubs 2, 3, 4 # encoding: [0x10,0x43,0x22,0x00]
+ vaddubs 2, 3, 4
+# CHECK: vadduhs 2, 3, 4 # encoding: [0x10,0x43,0x22,0x40]
+ vadduhs 2, 3, 4
+# CHECK: vadduws 2, 3, 4 # encoding: [0x10,0x43,0x22,0x80]
+ vadduws 2, 3, 4
+
+# CHECK: vsubcuw 2, 3, 4 # encoding: [0x10,0x43,0x25,0x80]
+ vsubcuw 2, 3, 4
+# CHECK: vsubsbs 2, 3, 4 # encoding: [0x10,0x43,0x27,0x00]
+ vsubsbs 2, 3, 4
+# CHECK: vsubshs 2, 3, 4 # encoding: [0x10,0x43,0x27,0x40]
+ vsubshs 2, 3, 4
+# CHECK: vsubsws 2, 3, 4 # encoding: [0x10,0x43,0x27,0x80]
+ vsubsws 2, 3, 4
+# CHECK: vsububm 2, 3, 4 # encoding: [0x10,0x43,0x24,0x00]
+ vsububm 2, 3, 4
+# CHECK: vsubuhm 2, 3, 4 # encoding: [0x10,0x43,0x24,0x40]
+ vsubuhm 2, 3, 4
+# CHECK: vsubuwm 2, 3, 4 # encoding: [0x10,0x43,0x24,0x80]
+ vsubuwm 2, 3, 4
+# CHECK: vsububs 2, 3, 4 # encoding: [0x10,0x43,0x26,0x00]
+ vsububs 2, 3, 4
+# CHECK: vsubuhs 2, 3, 4 # encoding: [0x10,0x43,0x26,0x40]
+ vsubuhs 2, 3, 4
+# CHECK: vsubuws 2, 3, 4 # encoding: [0x10,0x43,0x26,0x80]
+ vsubuws 2, 3, 4
+
+# CHECK: vmulesb 2, 3, 4 # encoding: [0x10,0x43,0x23,0x08]
+ vmulesb 2, 3, 4
+# CHECK: vmulesh 2, 3, 4 # encoding: [0x10,0x43,0x23,0x48]
+ vmulesh 2, 3, 4
+# CHECK: vmuleub 2, 3, 4 # encoding: [0x10,0x43,0x22,0x08]
+ vmuleub 2, 3, 4
+# CHECK: vmuleuh 2, 3, 4 # encoding: [0x10,0x43,0x22,0x48]
+ vmuleuh 2, 3, 4
+# CHECK: vmulosb 2, 3, 4 # encoding: [0x10,0x43,0x21,0x08]
+ vmulosb 2, 3, 4
+# CHECK: vmulosh 2, 3, 4 # encoding: [0x10,0x43,0x21,0x48]
+ vmulosh 2, 3, 4
+# CHECK: vmuloub 2, 3, 4 # encoding: [0x10,0x43,0x20,0x08]
+ vmuloub 2, 3, 4
+# CHECK: vmulouh 2, 3, 4 # encoding: [0x10,0x43,0x20,0x48]
+ vmulouh 2, 3, 4
+
+# CHECK: vmhaddshs 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x60]
+ vmhaddshs 2, 3, 4, 5
+# CHECK: vmhraddshs 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x61]
+ vmhraddshs 2, 3, 4, 5
+# CHECK: vmladduhm 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x62]
+ vmladduhm 2, 3, 4, 5
+# CHECK: vmsumubm 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x64]
+ vmsumubm 2, 3, 4, 5
+# CHECK: vmsummbm 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x65]
+ vmsummbm 2, 3, 4, 5
+# CHECK: vmsumshm 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x68]
+ vmsumshm 2, 3, 4, 5
+# CHECK: vmsumshs 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x69]
+ vmsumshs 2, 3, 4, 5
+# CHECK: vmsumuhm 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x66]
+ vmsumuhm 2, 3, 4, 5
+# CHECK: vmsumuhs 2, 3, 4, 5 # encoding: [0x10,0x43,0x21,0x67]
+ vmsumuhs 2, 3, 4, 5
+
+# CHECK: vsumsws 2, 3, 4 # encoding: [0x10,0x43,0x27,0x88]
+ vsumsws 2, 3, 4
+# CHECK: vsum2sws 2, 3, 4 # encoding: [0x10,0x43,0x26,0x88]
+ vsum2sws 2, 3, 4
+# CHECK: vsum4sbs 2, 3, 4 # encoding: [0x10,0x43,0x27,0x08]
+ vsum4sbs 2, 3, 4
+# CHECK: vsum4shs 2, 3, 4 # encoding: [0x10,0x43,0x26,0x48]
+ vsum4shs 2, 3, 4
+# CHECK: vsum4ubs 2, 3, 4 # encoding: [0x10,0x43,0x26,0x08]
+ vsum4ubs 2, 3, 4
+
+# CHECK: vavgsb 2, 3, 4 # encoding: [0x10,0x43,0x25,0x02]
+ vavgsb 2, 3, 4
+# CHECK: vavgsh 2, 3, 4 # encoding: [0x10,0x43,0x25,0x42]
+ vavgsh 2, 3, 4
+# CHECK: vavgsw 2, 3, 4 # encoding: [0x10,0x43,0x25,0x82]
+ vavgsw 2, 3, 4
+# CHECK: vavgub 2, 3, 4 # encoding: [0x10,0x43,0x24,0x02]
+ vavgub 2, 3, 4
+# CHECK: vavguh 2, 3, 4 # encoding: [0x10,0x43,0x24,0x42]
+ vavguh 2, 3, 4
+# CHECK: vavguw 2, 3, 4 # encoding: [0x10,0x43,0x24,0x82]
+ vavguw 2, 3, 4
+
+# CHECK: vmaxsb 2, 3, 4 # encoding: [0x10,0x43,0x21,0x02]
+ vmaxsb 2, 3, 4
+# CHECK: vmaxsh 2, 3, 4 # encoding: [0x10,0x43,0x21,0x42]
+ vmaxsh 2, 3, 4
+# CHECK: vmaxsw 2, 3, 4 # encoding: [0x10,0x43,0x21,0x82]
+ vmaxsw 2, 3, 4
+# CHECK: vmaxub 2, 3, 4 # encoding: [0x10,0x43,0x20,0x02]
+ vmaxub 2, 3, 4
+# CHECK: vmaxuh 2, 3, 4 # encoding: [0x10,0x43,0x20,0x42]
+ vmaxuh 2, 3, 4
+# CHECK: vmaxuw 2, 3, 4 # encoding: [0x10,0x43,0x20,0x82]
+ vmaxuw 2, 3, 4
+
+# CHECK: vminsb 2, 3, 4 # encoding: [0x10,0x43,0x23,0x02]
+ vminsb 2, 3, 4
+# CHECK: vminsh 2, 3, 4 # encoding: [0x10,0x43,0x23,0x42]
+ vminsh 2, 3, 4
+# CHECK: vminsw 2, 3, 4 # encoding: [0x10,0x43,0x23,0x82]
+ vminsw 2, 3, 4
+# CHECK: vminub 2, 3, 4 # encoding: [0x10,0x43,0x22,0x02]
+ vminub 2, 3, 4
+# CHECK: vminuh 2, 3, 4 # encoding: [0x10,0x43,0x22,0x42]
+ vminuh 2, 3, 4
+# CHECK: vminuw 2, 3, 4 # encoding: [0x10,0x43,0x22,0x82]
+ vminuw 2, 3, 4
+
+# Vector integer compare instructions
+
+# CHECK: vcmpequb 2, 3, 4 # encoding: [0x10,0x43,0x20,0x06]
+ vcmpequb 2, 3, 4
+# CHECK: vcmpequb. 2, 3, 4 # encoding: [0x10,0x43,0x24,0x06]
+ vcmpequb. 2, 3, 4
+# CHECK: vcmpequh 2, 3, 4 # encoding: [0x10,0x43,0x20,0x46]
+ vcmpequh 2, 3, 4
+# CHECK: vcmpequh. 2, 3, 4 # encoding: [0x10,0x43,0x24,0x46]
+ vcmpequh. 2, 3, 4
+# CHECK: vcmpequw 2, 3, 4 # encoding: [0x10,0x43,0x20,0x86]
+ vcmpequw 2, 3, 4
+# CHECK: vcmpequw. 2, 3, 4 # encoding: [0x10,0x43,0x24,0x86]
+ vcmpequw. 2, 3, 4
+# CHECK: vcmpgtsb 2, 3, 4 # encoding: [0x10,0x43,0x23,0x06]
+ vcmpgtsb 2, 3, 4
+# CHECK: vcmpgtsb. 2, 3, 4 # encoding: [0x10,0x43,0x27,0x06]
+ vcmpgtsb. 2, 3, 4
+# CHECK: vcmpgtsh 2, 3, 4 # encoding: [0x10,0x43,0x23,0x46]
+ vcmpgtsh 2, 3, 4
+# CHECK: vcmpgtsh. 2, 3, 4 # encoding: [0x10,0x43,0x27,0x46]
+ vcmpgtsh. 2, 3, 4
+# CHECK: vcmpgtsw 2, 3, 4 # encoding: [0x10,0x43,0x23,0x86]
+ vcmpgtsw 2, 3, 4
+# CHECK: vcmpgtsw. 2, 3, 4 # encoding: [0x10,0x43,0x27,0x86]
+ vcmpgtsw. 2, 3, 4
+# CHECK: vcmpgtub 2, 3, 4 # encoding: [0x10,0x43,0x22,0x06]
+ vcmpgtub 2, 3, 4
+# CHECK: vcmpgtub. 2, 3, 4 # encoding: [0x10,0x43,0x26,0x06]
+ vcmpgtub. 2, 3, 4
+# CHECK: vcmpgtuh 2, 3, 4 # encoding: [0x10,0x43,0x22,0x46]
+ vcmpgtuh 2, 3, 4
+# CHECK: vcmpgtuh. 2, 3, 4 # encoding: [0x10,0x43,0x26,0x46]
+ vcmpgtuh. 2, 3, 4
+# CHECK: vcmpgtuw 2, 3, 4 # encoding: [0x10,0x43,0x22,0x86]
+ vcmpgtuw 2, 3, 4
+# CHECK: vcmpgtuw. 2, 3, 4 # encoding: [0x10,0x43,0x26,0x86]
+ vcmpgtuw. 2, 3, 4
+
+# Vector integer logical instructions
+
+# CHECK: vand 2, 3, 4 # encoding: [0x10,0x43,0x24,0x04]
+ vand 2, 3, 4
+# CHECK: vandc 2, 3, 4 # encoding: [0x10,0x43,0x24,0x44]
+ vandc 2, 3, 4
+# CHECK: vnor 2, 3, 4 # encoding: [0x10,0x43,0x25,0x04]
+ vnor 2, 3, 4
+# CHECK: vor 2, 3, 4 # encoding: [0x10,0x43,0x24,0x84]
+ vor 2, 3, 4
+# CHECK: vxor 2, 3, 4 # encoding: [0x10,0x43,0x24,0xc4]
+ vxor 2, 3, 4
+
+# Vector integer rotate and shift instructions
+
+# CHECK: vrlb 2, 3, 4 # encoding: [0x10,0x43,0x20,0x04]
+ vrlb 2, 3, 4
+# CHECK: vrlh 2, 3, 4 # encoding: [0x10,0x43,0x20,0x44]
+ vrlh 2, 3, 4
+# CHECK: vrlw 2, 3, 4 # encoding: [0x10,0x43,0x20,0x84]
+ vrlw 2, 3, 4
+
+# CHECK: vslb 2, 3, 4 # encoding: [0x10,0x43,0x21,0x04]
+ vslb 2, 3, 4
+# CHECK: vslh 2, 3, 4 # encoding: [0x10,0x43,0x21,0x44]
+ vslh 2, 3, 4
+# CHECK: vslw 2, 3, 4 # encoding: [0x10,0x43,0x21,0x84]
+ vslw 2, 3, 4
+# CHECK: vsrb 2, 3, 4 # encoding: [0x10,0x43,0x22,0x04]
+ vsrb 2, 3, 4
+# CHECK: vsrh 2, 3, 4 # encoding: [0x10,0x43,0x22,0x44]
+ vsrh 2, 3, 4
+# CHECK: vsrw 2, 3, 4 # encoding: [0x10,0x43,0x22,0x84]
+ vsrw 2, 3, 4
+# CHECK: vsrab 2, 3, 4 # encoding: [0x10,0x43,0x23,0x04]
+ vsrab 2, 3, 4
+# CHECK: vsrah 2, 3, 4 # encoding: [0x10,0x43,0x23,0x44]
+ vsrah 2, 3, 4
+# CHECK: vsraw 2, 3, 4 # encoding: [0x10,0x43,0x23,0x84]
+ vsraw 2, 3, 4
+
+# Vector floating-point instructions
+
+# CHECK: vaddfp 2, 3, 4 # encoding: [0x10,0x43,0x20,0x0a]
+ vaddfp 2, 3, 4
+# CHECK: vsubfp 2, 3, 4 # encoding: [0x10,0x43,0x20,0x4a]
+ vsubfp 2, 3, 4
+# CHECK: vmaddfp 2, 3, 4, 5 # encoding: [0x10,0x43,0x29,0x2e]
+ vmaddfp 2, 3, 4, 5
+# CHECK: vnmsubfp 2, 3, 4, 5 # encoding: [0x10,0x43,0x29,0x2f]
+ vnmsubfp 2, 3, 4, 5
+
+# CHECK: vmaxfp 2, 3, 4 # encoding: [0x10,0x43,0x24,0x0a]
+ vmaxfp 2, 3, 4
+# CHECK: vminfp 2, 3, 4 # encoding: [0x10,0x43,0x24,0x4a]
+ vminfp 2, 3, 4
+
+# CHECK: vctsxs 2, 3, 4 # encoding: [0x10,0x44,0x1b,0xca]
+ vctsxs 2, 3, 4
+# CHECK: vctuxs 2, 3, 4 # encoding: [0x10,0x44,0x1b,0x8a]
+ vctuxs 2, 3, 4
+# CHECK: vcfsx 2, 3, 4 # encoding: [0x10,0x44,0x1b,0x4a]
+ vcfsx 2, 3, 4
+# CHECK: vcfux 2, 3, 4 # encoding: [0x10,0x44,0x1b,0x0a]
+ vcfux 2, 3, 4
+# CHECK: vrfim 2, 3 # encoding: [0x10,0x40,0x1a,0xca]
+ vrfim 2, 3
+# CHECK: vrfin 2, 3 # encoding: [0x10,0x40,0x1a,0x0a]
+ vrfin 2, 3
+# CHECK: vrfip 2, 3 # encoding: [0x10,0x40,0x1a,0x8a]
+ vrfip 2, 3
+# CHECK: vrfiz 2, 3 # encoding: [0x10,0x40,0x1a,0x4a]
+ vrfiz 2, 3
+
+# CHECK: vcmpbfp 2, 3, 4 # encoding: [0x10,0x43,0x23,0xc6]
+ vcmpbfp 2, 3, 4
+# CHECK: vcmpbfp. 2, 3, 4 # encoding: [0x10,0x43,0x27,0xc6]
+ vcmpbfp. 2, 3, 4
+# CHECK: vcmpeqfp 2, 3, 4 # encoding: [0x10,0x43,0x20,0xc6]
+ vcmpeqfp 2, 3, 4
+# CHECK: vcmpeqfp. 2, 3, 4 # encoding: [0x10,0x43,0x24,0xc6]
+ vcmpeqfp. 2, 3, 4
+# CHECK: vcmpgefp 2, 3, 4 # encoding: [0x10,0x43,0x21,0xc6]
+ vcmpgefp 2, 3, 4
+# CHECK: vcmpgefp. 2, 3, 4 # encoding: [0x10,0x43,0x25,0xc6]
+ vcmpgefp. 2, 3, 4
+# CHECK: vcmpgtfp 2, 3, 4 # encoding: [0x10,0x43,0x22,0xc6]
+ vcmpgtfp 2, 3, 4
+# CHECK: vcmpgtfp. 2, 3, 4 # encoding: [0x10,0x43,0x26,0xc6]
+ vcmpgtfp. 2, 3, 4
+
+# CHECK: vexptefp 2, 3 # encoding: [0x10,0x40,0x19,0x8a]
+ vexptefp 2, 3
+# CHECK: vlogefp 2, 3 # encoding: [0x10,0x40,0x19,0xca]
+ vlogefp 2, 3
+# CHECK: vrefp 2, 3 # encoding: [0x10,0x40,0x19,0x0a]
+ vrefp 2, 3
+# CHECK: vrsqrtefp 2, 3 # encoding: [0x10,0x40,0x19,0x4a]
+ vrsqrtefp 2, 3
+
+# Vector status and control register instructions
+
+# CHECK: mtvscr 2 # encoding: [0x10,0x00,0x16,0x44]
+ mtvscr 2
+# CHECK: mfvscr 2 # encoding: [0x10,0x40,0x06,0x04]
+ mfvscr 2
+
diff --git a/llvm/test/MC/PowerPC/ppc64-encoding.s b/llvm/test/MC/PowerPC/ppc64-encoding.s
new file mode 100644
index 00000000000..dda79606384
--- /dev/null
+++ b/llvm/test/MC/PowerPC/ppc64-encoding.s
@@ -0,0 +1,480 @@
+
+# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck %s
+
+# Branch facility
+
+# Branch instructions
+
+# CHECK: b target # encoding: [0b010010AA,A,A,0bAAAAAA00]
+# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_br24
+ b target
+# FIXME: ba target
+# CHECK: bl target # encoding: [0b010010AA,A,A,0bAAAAAA01]
+# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_br24
+ bl target
+# FIXME: bla target
+
+# FIXME: bc 4, 10, target
+# FIXME: bca 4, 10, target
+# FIXME: bcl 4, 10, target
+# FIXME: bcla 4, 10, target
+
+# FIXME: bclr 4, 10, 3
+# FIXME: bclrl 4, 10, 3
+# FIXME: bcctr 4, 10, 3
+# FIXME: bcctrl 4, 10, 3
+
+# Condition register instructions
+
+# FIXME: crand 2, 3, 4
+# FIXME: crnand 2, 3, 4
+# CHECK: cror 2, 3, 4 # encoding: [0x4c,0x43,0x23,0x82]
+ cror 2, 3, 4
+# FIXME: crxor 2, 3, 4
+# FIXME: crnor 2, 3, 4
+# CHECK: creqv 2, 3, 4 # encoding: [0x4c,0x43,0x22,0x42]
+ creqv 2, 3, 4
+# FIXME: crandc 2, 3, 4
+# FIXME: crorc 2, 3, 4
+# CHECK: mcrf 2, 3 # encoding: [0x4d,0x0c,0x00,0x00]
+ mcrf 2, 3
+
+# System call instruction
+
+# FIXME: sc 1
+
+# Fixed-point facility
+
+# Fixed-point load instructions
+
+# CHECK: lbz 2, 128(4) # encoding: [0x88,0x44,0x00,0x80]
+ lbz 2, 128(4)
+# CHECK: lbzx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0xae]
+ lbzx 2, 3, 4
+# CHECK: lbzu 2, 128(4) # encoding: [0x8c,0x44,0x00,0x80]
+ lbzu 2, 128(4)
+# CHECK: lbzux 2, 3, 4 # encoding: [0x7c,0x43,0x20,0xee]
+ lbzux 2, 3, 4
+# CHECK: lhz 2, 128(4) # encoding: [0xa0,0x44,0x00,0x80]
+ lhz 2, 128(4)
+# CHECK: lhzx 2, 3, 4 # encoding: [0x7c,0x43,0x22,0x2e]
+ lhzx 2, 3, 4
+# CHECK: lhzu 2, 128(4) # encoding: [0xa4,0x44,0x00,0x80]
+ lhzu 2, 128(4)
+# CHECK: lhzux 2, 3, 4 # encoding: [0x7c,0x43,0x22,0x6e]
+ lhzux 2, 3, 4
+# CHECK: lha 2, 128(4) # encoding: [0xa8,0x44,0x00,0x80]
+ lha 2, 128(4)
+# CHECK: lhax 2, 3, 4 # encoding: [0x7c,0x43,0x22,0xae]
+ lhax 2, 3, 4
+# CHECK: lhau 2, 128(4) # encoding: [0xac,0x44,0x00,0x80]
+ lhau 2, 128(4)
+# CHECK: lhaux 2, 3, 4 # encoding: [0x7c,0x43,0x22,0xee]
+ lhaux 2, 3, 4
+# CHECK: lwz 2, 128(4) # encoding: [0x80,0x44,0x00,0x80]
+ lwz 2, 128(4)
+# CHECK: lwzx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x2e]
+ lwzx 2, 3, 4
+# CHECK: lwzu 2, 128(4) # encoding: [0x84,0x44,0x00,0x80]
+ lwzu 2, 128(4)
+# CHECK: lwzux 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x6e]
+ lwzux 2, 3, 4
+# CHECK: lwa 2, 128(4) # encoding: [0xe8,0x44,0x00,0x82]
+ lwa 2, 128(4)
+# CHECK: lwax 2, 3, 4 # encoding: [0x7c,0x43,0x22,0xaa]
+ lwax 2, 3, 4
+# CHECK: lwaux 2, 3, 4 # encoding: [0x7c,0x43,0x22,0xea]
+ lwaux 2, 3, 4
+# CHECK: ld 2, 128(4) # encoding: [0xe8,0x44,0x00,0x80]
+ ld 2, 128(4)
+# CHECK: ldx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x2a]
+ ldx 2, 3, 4
+# CHECK: ldu 2, 128(4) # encoding: [0xe8,0x44,0x00,0x81]
+ ldu 2, 128(4)
+# CHECK: ldux 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x6a]
+ ldux 2, 3, 4
+
+# Fixed-point store instructions
+
+# CHECK: stb 2, 128(4) # encoding: [0x98,0x44,0x00,0x80]
+ stb 2, 128(4)
+# CHECK: stbx 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xae]
+ stbx 2, 3, 4
+# CHECK: stbu 2, 128(4) # encoding: [0x9c,0x44,0x00,0x80]
+ stbu 2, 128(4)
+# CHECK: stbux 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xee]
+ stbux 2, 3, 4
+# CHECK: sth 2, 128(4) # encoding: [0xb0,0x44,0x00,0x80]
+ sth 2, 128(4)
+# CHECK: sthx 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x2e]
+ sthx 2, 3, 4
+# CHECK: sthu 2, 128(4) # encoding: [0xb4,0x44,0x00,0x80]
+ sthu 2, 128(4)
+# CHECK: sthux 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x6e]
+ sthux 2, 3, 4
+# CHECK: stw 2, 128(4) # encoding: [0x90,0x44,0x00,0x80]
+ stw 2, 128(4)
+# CHECK: stwx 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x2e]
+ stwx 2, 3, 4
+# CHECK: stwu 2, 128(4) # encoding: [0x94,0x44,0x00,0x80]
+ stwu 2, 128(4)
+# CHECK: stwux 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x6e]
+ stwux 2, 3, 4
+# CHECK: std 2, 128(4) # encoding: [0xf8,0x44,0x00,0x80]
+ std 2, 128(4)
+# CHECK: stdx 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x2a]
+ stdx 2, 3, 4
+# CHECK: stdu 2, 128(4) # encoding: [0xf8,0x44,0x00,0x81]
+ stdu 2, 128(4)
+# CHECK: stdux 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x6a]
+ stdux 2, 3, 4
+
+# Fixed-point load and store with byte reversal instructions
+
+# CHECK: lhbrx 2, 3, 4 # encoding: [0x7c,0x43,0x26,0x2c]
+ lhbrx 2, 3, 4
+# CHECK: sthbrx 2, 3, 4 # encoding: [0x7c,0x43,0x27,0x2c]
+ sthbrx 2, 3, 4
+# CHECK: lwbrx 2, 3, 4 # encoding: [0x7c,0x43,0x24,0x2c]
+ lwbrx 2, 3, 4
+# CHECK: stwbrx 2, 3, 4 # encoding: [0x7c,0x43,0x25,0x2c]
+ stwbrx 2, 3, 4
+# CHECK: ldbrx 2, 3, 4 # encoding: [0x7c,0x43,0x24,0x28]
+ ldbrx 2, 3, 4
+# CHECK: stdbrx 2, 3, 4 # encoding: [0x7c,0x43,0x25,0x28]
+ stdbrx 2, 3, 4
+
+# FIXME: Fixed-point load and store multiple instructions
+
+# FIXME: Fixed-point move assist instructions
+
+# Fixed-point arithmetic instructions
+
+# CHECK: addi 2, 3, 128 # encoding: [0x38,0x43,0x00,0x80]
+ addi 2, 3, 128
+# CHECK: addis 2, 3, 128 # encoding: [0x3c,0x43,0x00,0x80]
+ addis 2, 3, 128
+# CHECK: add 2, 3, 4 # encoding: [0x7c,0x43,0x22,0x14]
+ add 2, 3, 4
+# CHECK: add. 2, 3, 4 # encoding: [0x7c,0x43,0x22,0x15]
+ add. 2, 3, 4
+# FIXME: addo 2, 3, 4
+# FIXME: addo. 2, 3, 4
+# CHECK: subf 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x50]
+ subf 2, 3, 4
+# CHECK: subf. 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x51]
+ subf. 2, 3, 4
+# FIXME: subfo 2, 3, 4
+# FIXME: subfo. 2, 3, 4
+# CHECK: addic 2, 3, 128 # encoding: [0x30,0x43,0x00,0x80]
+ addic 2, 3, 128
+# CHECK: addic. 2, 3, 128 # encoding: [0x34,0x43,0x00,0x80]
+ addic. 2, 3, 128
+# CHECK: subfic 2, 3, 4 # encoding: [0x20,0x43,0x00,0x04]
+ subfic 2, 3, 4
+
+# CHECK: addc 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x14]
+ addc 2, 3, 4
+# CHECK: addc. 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x15]
+ addc. 2, 3, 4
+# FIXME: addco 2, 3, 4
+# FIXME: addco. 2, 3, 4
+# CHECK: subfc 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x10]
+ subfc 2, 3, 4
+# CHECK: subfc 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x10]
+ subfc 2, 3, 4
+# FIXME: subfco 2, 3, 4
+# FIXME: subfco. 2, 3, 4
+
+# CHECK: adde 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x14]
+ adde 2, 3, 4
+# CHECK: adde. 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x15]
+ adde. 2, 3, 4
+# FIXME: addeo 2, 3, 4
+# FIXME: addeo. 2, 3, 4
+# CHECK: subfe 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x10]
+ subfe 2, 3, 4
+# CHECK: subfe. 2, 3, 4 # encoding: [0x7c,0x43,0x21,0x11]
+ subfe. 2, 3, 4
+# FIXME: subfeo 2, 3, 4
+# FIXME: subfeo. 2, 3, 4
+
+# CHECK: addme 2, 3 # encoding: [0x7c,0x43,0x01,0xd4]
+ addme 2, 3
+# CHECK: addme. 2, 3 # encoding: [0x7c,0x43,0x01,0xd5]
+ addme. 2, 3
+# FIXME: addmeo 2, 3
+# FIXME: addmeo. 2, 3
+# CHECK: subfme 2, 3 # encoding: [0x7c,0x43,0x01,0xd0]
+ subfme 2, 3
+# CHECK: subfme. 2, 3 # encoding: [0x7c,0x43,0x01,0xd1]
+ subfme. 2, 3
+# FIXME: subfmeo 2, 3
+# FIXME: subfmeo. 2, 3
+
+# CHECK: addze 2, 3 # encoding: [0x7c,0x43,0x01,0x94]
+ addze 2, 3
+# CHECK: addze. 2, 3 # encoding: [0x7c,0x43,0x01,0x95]
+ addze. 2, 3
+# FIXME: addzeo 2, 3
+# FIXME: addzeo. 2, 3
+# CHECK: subfze 2, 3 # encoding: [0x7c,0x43,0x01,0x90]
+ subfze 2, 3
+# CHECK: subfze. 2, 3 # encoding: [0x7c,0x43,0x01,0x91]
+ subfze. 2, 3
+# FIXME: subfzeo 2, 3
+# FIXME: subfzeo. 2, 3
+
+# CHECK: neg 2, 3 # encoding: [0x7c,0x43,0x00,0xd0]
+ neg 2, 3
+# CHECK: neg. 2, 3 # encoding: [0x7c,0x43,0x00,0xd1]
+ neg. 2, 3
+# FIXME: nego 2, 3
+# FIXME: nego. 2, 3
+
+# CHECK: mulli 2, 3, 128 # encoding: [0x1c,0x43,0x00,0x80]
+ mulli 2, 3, 128
+# CHECK: mulhw 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x96]
+ mulhw 2, 3, 4
+# CHECK: mulhw. 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x97]
+ mulhw. 2, 3, 4
+# CHECK: mullw 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xd6]
+ mullw 2, 3, 4
+# CHECK: mullw. 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xd7]
+ mullw. 2, 3, 4
+# FIXME: mullwo 2, 3, 4
+# FIXME: mullwo. 2, 3, 4
+# CHECK: mulhwu 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x16]
+ mulhwu 2, 3, 4
+# CHECK: mulhwu. 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x17]
+ mulhwu. 2, 3, 4
+
+# CHECK: divw 2, 3, 4 # encoding: [0x7c,0x43,0x23,0xd6]
+ divw 2, 3, 4
+# CHECK: divw. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0xd7]
+ divw. 2, 3, 4
+# FIXME: divwo 2, 3, 4
+# FIXME: divwo. 2, 3, 4
+# CHECK: divwu 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x96]
+ divwu 2, 3, 4
+# CHECK: divwu. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x97]
+ divwu. 2, 3, 4
+# FIXME: divwuo 2, 3, 4
+# FIXME: divwuo. 2, 3, 4
+# FIXME: divwe 2, 3, 4
+# FIXME: divwe. 2, 3, 4
+# FIXME: divweo 2, 3, 4
+# FIXME: divweo. 2, 3, 4
+# FIXME: divweu 2, 3, 4
+# FIXME: divweu. 2, 3, 4
+# FIXME: divweuo 2, 3, 4
+# FIXME: divweuo. 2, 3, 4
+
+# CHECK: mulld 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xd2]
+ mulld 2, 3, 4
+# CHECK: mulld. 2, 3, 4 # encoding: [0x7c,0x43,0x21,0xd3]
+ mulld. 2, 3, 4
+# FIXME: mulldo 2, 3, 4
+# FIXME: mulldo. 2, 3, 4
+# CHECK: mulhd 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x92]
+ mulhd 2, 3, 4
+# CHECK: mulhd. 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x93]
+ mulhd. 2, 3, 4
+# CHECK: mulhdu 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x12]
+ mulhdu 2, 3, 4
+# CHECK: mulhdu. 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x13]
+ mulhdu. 2, 3, 4
+
+# CHECK: divd 2, 3, 4 # encoding: [0x7c,0x43,0x23,0xd2]
+ divd 2, 3, 4
+# CHECK: divd. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0xd3]
+ divd. 2, 3, 4
+# FIXME: divdo 2, 3, 4
+# FIXME: divdo. 2, 3, 4
+# CHECK: divdu 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x92]
+ divdu 2, 3, 4
+# CHECK: divdu. 2, 3, 4 # encoding: [0x7c,0x43,0x23,0x93]
+ divdu. 2, 3, 4
+# FIXME: divduo 2, 3, 4
+# FIXME: divduo. 2, 3, 4
+# FIXME: divde 2, 3, 4
+# FIXME: divde. 2, 3, 4
+# FIXME: divdeo 2, 3, 4
+# FIXME: divdeo. 2, 3, 4
+# FIXME: divdeu 2, 3, 4
+# FIXME: divdeu. 2, 3, 4
+# FIXME: divdeuo 2, 3, 4
+# FIXME: divdeuo. 2, 3, 4
+
+# FIXME: Fixed-point compare instructions
+
+# FIXME: Fixed-point trap instructions
+
+# Fixed-point select
+
+# CHECK: isel 2, 3, 4, 5 # encoding: [0x7c,0x43,0x21,0x5e]
+ isel 2, 3, 4, 5
+
+# Fixed-point logical instructions
+
+# CHECK: andi. 2, 3, 128 # encoding: [0x70,0x62,0x00,0x80]
+ andi. 2, 3, 128
+# CHECK: andis. 2, 3, 128 # encoding: [0x74,0x62,0x00,0x80]
+ andis. 2, 3, 128
+# CHECK: ori 2, 3, 128 # encoding: [0x60,0x62,0x00,0x80]
+ ori 2, 3, 128
+# CHECK: oris 2, 3, 128 # encoding: [0x64,0x62,0x00,0x80]
+ oris 2, 3, 128
+# CHECK: xori 2, 3, 128 # encoding: [0x68,0x62,0x00,0x80]
+ xori 2, 3, 128
+# CHECK: xoris 2, 3, 128 # encoding: [0x6c,0x62,0x00,0x80]
+ xoris 2, 3, 128
+# CHECK: and 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x38]
+ and 2, 3, 4
+# CHECK: and. 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x39]
+ and. 2, 3, 4
+# CHECK: xor 2, 3, 4 # encoding: [0x7c,0x62,0x22,0x78]
+ xor 2, 3, 4
+# CHECK: xor. 2, 3, 4 # encoding: [0x7c,0x62,0x22,0x79]
+ xor. 2, 3, 4
+# CHECK: nand 2, 3, 4 # encoding: [0x7c,0x62,0x23,0xb8]
+ nand 2, 3, 4
+# CHECK: nand. 2, 3, 4 # encoding: [0x7c,0x62,0x23,0xb9]
+ nand. 2, 3, 4
+# CHECK: or 2, 3, 4 # encoding: [0x7c,0x62,0x23,0x78]
+ or 2, 3, 4
+# CHECK: or. 2, 3, 4 # encoding: [0x7c,0x62,0x23,0x79]
+ or. 2, 3, 4
+# CHECK: nor 2, 3, 4 # encoding: [0x7c,0x62,0x20,0xf8]
+ nor 2, 3, 4
+# CHECK: nor. 2, 3, 4 # encoding: [0x7c,0x62,0x20,0xf9]
+ nor. 2, 3, 4
+# CHECK: eqv 2, 3, 4 # encoding: [0x7c,0x62,0x22,0x38]
+ eqv 2, 3, 4
+# CHECK: eqv. 2, 3, 4 # encoding: [0x7c,0x62,0x22,0x39]
+ eqv. 2, 3, 4
+# CHECK: andc 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x78]
+ andc 2, 3, 4
+# CHECK: andc. 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x79]
+ andc. 2, 3, 4
+# CHECK: orc 2, 3, 4 # encoding: [0x7c,0x62,0x23,0x38]
+ orc 2, 3, 4
+# CHECK: orc. 2, 3, 4 # encoding: [0x7c,0x62,0x23,0x39]
+ orc. 2, 3, 4
+
+# CHECK: extsb 2, 3 # encoding: [0x7c,0x62,0x07,0x74]
+ extsb 2, 3
+# CHECK: extsb. 2, 3 # encoding: [0x7c,0x62,0x07,0x75]
+ extsb. 2, 3
+# CHECK: extsh 2, 3 # encoding: [0x7c,0x62,0x07,0x34]
+ extsh 2, 3
+# CHECK: extsh. 2, 3 # encoding: [0x7c,0x62,0x07,0x35]
+ extsh. 2, 3
+
+# CHECK: cntlzw 2, 3 # encoding: [0x7c,0x62,0x00,0x34]
+ cntlzw 2, 3
+# CHECK: cntlzw. 2, 3 # encoding: [0x7c,0x62,0x00,0x35]
+ cntlzw. 2, 3
+# FIXME: cmpb 2, 3, 4
+# FIXME: popcntb 2, 3
+# CHECK: popcntw 2, 3 # encoding: [0x7c,0x62,0x02,0xf4]
+ popcntw 2, 3
+# FIXME: prtyd 2, 3
+# FIXME: prtyw 2, 3
+
+# CHECK: extsw 2, 3 # encoding: [0x7c,0x62,0x07,0xb4]
+ extsw 2, 3
+# CHECK: extsw. 2, 3 # encoding: [0x7c,0x62,0x07,0xb5]
+ extsw. 2, 3
+
+# CHECK: cntlzd 2, 3 # encoding: [0x7c,0x62,0x00,0x74]
+ cntlzd 2, 3
+# CHECK: cntlzd. 2, 3 # encoding: [0x7c,0x62,0x00,0x75]
+ cntlzd. 2, 3
+# CHECK: popcntd 2, 3 # encoding: [0x7c,0x62,0x03,0xf4]
+ popcntd 2, 3
+# FIXME: bpermd 2, 3, 4
+
+# Fixed-point rotate and shift instructions
+
+# CHECK: rlwinm 2, 3, 4, 5, 6 # encoding: [0x54,0x62,0x21,0x4c]
+ rlwinm 2, 3, 4, 5, 6
+# CHECK: rlwinm. 2, 3, 4, 5, 6 # encoding: [0x54,0x62,0x21,0x4d]
+ rlwinm. 2, 3, 4, 5, 6
+# CHECK: rlwnm 2, 3, 4, 5, 6 # encoding: [0x5c,0x62,0x21,0x4c]
+ rlwnm 2, 3, 4, 5, 6
+# CHECK: rlwnm. 2, 3, 4, 5, 6 # encoding: [0x5c,0x62,0x21,0x4d]
+ rlwnm. 2, 3, 4, 5, 6
+# CHECK: rlwimi 2, 3, 4, 5, 6 # encoding: [0x50,0x62,0x21,0x4c]
+ rlwimi 2, 3, 4, 5, 6
+# CHECK: rlwimi. 2, 3, 4, 5, 6 # encoding: [0x50,0x62,0x21,0x4d]
+ rlwimi. 2, 3, 4, 5, 6
+# CHECK: rldicl 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x40]
+ rldicl 2, 3, 4, 5
+# CHECK: rldicl. 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x41]
+ rldicl. 2, 3, 4, 5
+# CHECK: rldicr 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x44]
+ rldicr 2, 3, 4, 5
+# CHECK: rldicr. 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x45]
+ rldicr. 2, 3, 4, 5
+# FIXME: rldic 2, 3, 4, 5
+# FIXME: rldic. 2, 3, 4, 5
+# CHECK: rldcl 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x50]
+ rldcl 2, 3, 4, 5
+# CHECK: rldcl. 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x51]
+ rldcl. 2, 3, 4, 5
+# FIXME: rldcr 2, 3, 4, 5
+# FIXME: rldcr. 2, 3, 4, 5
+# CHECK: rldimi 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x4c]
+ rldimi 2, 3, 4, 5
+# CHECK: rldimi. 2, 3, 4, 5 # encoding: [0x78,0x62,0x21,0x4d]
+ rldimi. 2, 3, 4, 5
+
+# CHECK: slw 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x30]
+ slw 2, 3, 4
+# CHECK: slw. 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x31]
+ slw. 2, 3, 4
+# CHECK: srw 2, 3, 4 # encoding: [0x7c,0x62,0x24,0x30]
+ srw 2, 3, 4
+# CHECK: srw. 2, 3, 4 # encoding: [0x7c,0x62,0x24,0x31]
+ srw. 2, 3, 4
+# CHECK: srawi 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x70]
+ srawi 2, 3, 4
+# CHECK: srawi. 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x71]
+ srawi. 2, 3, 4
+# CHECK: sraw 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x30]
+ sraw 2, 3, 4
+# CHECK: sraw. 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x31]
+ sraw. 2, 3, 4
+# CHECK: sld 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x36]
+ sld 2, 3, 4
+# CHECK: sld. 2, 3, 4 # encoding: [0x7c,0x62,0x20,0x37]
+ sld. 2, 3, 4
+# CHECK: srd 2, 3, 4 # encoding: [0x7c,0x62,0x24,0x36]
+ srd 2, 3, 4
+# CHECK: srd. 2, 3, 4 # encoding: [0x7c,0x62,0x24,0x37]
+ srd. 2, 3, 4
+# CHECK: sradi 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x74]
+ sradi 2, 3, 4
+# CHECK: sradi. 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x75]
+ sradi. 2, 3, 4
+# CHECK: srad 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x34]
+ srad 2, 3, 4
+# CHECK: srad. 2, 3, 4 # encoding: [0x7c,0x62,0x26,0x35]
+ srad. 2, 3, 4
+
+# FIXME: BCD assist instructions
+
+# Move to/from system register instructions
+
+# FIXME: mtspr 256, 2
+# FIXME: mfspr 2, 256
+# CHECK: mtcrf 16, 2 # encoding: [0x7c,0x41,0x01,0x20]
+ mtcrf 16, 2
+# CHECK: mfcr 2 # encoding: [0x7c,0x40,0x00,0x26]
+ mfcr 2
+# FIXME: mtocrf 16, 2
+# CHECK: mfocrf 16, 8 # encoding: [0x7e,0x10,0x80,0x26]
+ mfocrf 16, 8
+# FIXME: mcrxr 2
+
diff --git a/llvm/test/MC/PowerPC/ppc64-errors.s b/llvm/test/MC/PowerPC/ppc64-errors.s
new file mode 100644
index 00000000000..1da57530460
--- /dev/null
+++ b/llvm/test/MC/PowerPC/ppc64-errors.s
@@ -0,0 +1,80 @@
+
+# RUN: not llvm-mc -triple powerpc64-unknown-unknown < %s 2> %t
+# RUN: FileCheck < %t %s
+
+# Register operands
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: add 32, 32, 32
+ add 32, 32, 32
+
+# CHECK: error: invalid register name
+# CHECK-NEXT: add %r32, %r32, %r32
+ add %r32, %r32, %r32
+
+# Signed 16-bit immediate operands
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: addi 1, 0, -32769
+ addi 1, 0, -32769
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: addi 1, 0, 32768
+ addi 1, 0, 32768
+
+# Unsigned 16-bit immediate operands
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: ori 1, 2, -1
+ ori 1, 2, -1
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: ori 1, 2, 65536
+ ori 1, 2, 65536
+
+# D-Form memory operands
+
+# CHECK: error: invalid register number
+# CHECK-NEXT: lwz 1, 0(32)
+ lwz 1, 0(32)
+
+# CHECK: error: invalid register name
+# CHECK-NEXT: lwz 1, 0(%r32)
+ lwz 1, 0(%r32)
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: lwz 1, -32769(2)
+ lwz 1, -32769(2)
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: lwz 1, 32768(2)
+ lwz 1, 32768(2)
+
+# CHECK: error: invalid register number
+# CHECK-NEXT: ld 1, 0(32)
+ ld 1, 0(32)
+
+# CHECK: error: invalid register name
+# CHECK-NEXT: ld 1, 0(%r32)
+ ld 1, 0(%r32)
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: ld 1, 1(2)
+ ld 1, 1(2)
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: ld 1, 2(2)
+ ld 1, 2(2)
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: ld 1, 3(2)
+ ld 1, 3(2)
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: ld 1, -32772(2)
+ ld 1, -32772(2)
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: ld 1, 32768(2)
+ ld 1, 32768(2)
+
diff --git a/llvm/test/MC/PowerPC/ppc64-operands.s b/llvm/test/MC/PowerPC/ppc64-operands.s
new file mode 100644
index 00000000000..de5fcb0e8d2
--- /dev/null
+++ b/llvm/test/MC/PowerPC/ppc64-operands.s
@@ -0,0 +1,87 @@
+
+# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck %s
+
+# Register operands
+
+# CHECK: add 1, 2, 3 # encoding: [0x7c,0x22,0x1a,0x14]
+ add 1, 2, 3
+
+# CHECK: add 1, 2, 3 # encoding: [0x7c,0x22,0x1a,0x14]
+ add %r1, %r2, %r3
+
+# CHECK: add 0, 0, 0 # encoding: [0x7c,0x00,0x02,0x14]
+ add 0, 0, 0
+
+# CHECK: add 31, 31, 31 # encoding: [0x7f,0xff,0xfa,0x14]
+ add 31, 31, 31
+
+# CHECK: addi 1, 0, 0 # encoding: [0x38,0x20,0x00,0x00]
+ addi 1, 0, 0
+
+# CHECK: addi 1, 0, 0 # encoding: [0x38,0x20,0x00,0x00]
+ addi 1, %r0, 0
+
+# Signed 16-bit immediate operands
+
+# CHECK: addi 1, 2, 0 # encoding: [0x38,0x22,0x00,0x00]
+ addi 1, 2, 0
+
+# CHECK: addi 1, 0, -32768 # encoding: [0x38,0x20,0x80,0x00]
+ addi 1, 0, -32768
+
+# CHECK: addi 1, 0, 32767 # encoding: [0x38,0x20,0x7f,0xff]
+ addi 1, 0, 32767
+
+# Unsigned 16-bit immediate operands
+
+# CHECK: ori 1, 2, 0 # encoding: [0x60,0x41,0x00,0x00]
+ ori 1, 2, 0
+
+# CHECK: ori 1, 2, 65535 # encoding: [0x60,0x41,0xff,0xff]
+ ori 1, 2, 65535
+
+# D-Form memory operands
+
+# CHECK: lwz 1, 0(0) # encoding: [0x80,0x20,0x00,0x00]
+ lwz 1, 0(0)
+
+# CHECK: lwz 1, 0(0) # encoding: [0x80,0x20,0x00,0x00]
+ lwz 1, 0(%r0)
+
+# CHECK: lwz 1, 0(31) # encoding: [0x80,0x3f,0x00,0x00]
+ lwz 1, 0(31)
+
+# CHECK: lwz 1, 0(31) # encoding: [0x80,0x3f,0x00,0x00]
+ lwz 1, 0(%r31)
+
+# CHECK: lwz 1, -32768(2) # encoding: [0x80,0x22,0x80,0x00]
+ lwz 1, -32768(2)
+
+# CHECK: lwz 1, 32767(2) # encoding: [0x80,0x22,0x7f,0xff]
+ lwz 1, 32767(2)
+
+
+# CHECK: ld 1, 0(0) # encoding: [0xe8,0x20,0x00,0x00]
+ ld 1, 0(0)
+
+# CHECK: ld 1, 0(0) # encoding: [0xe8,0x20,0x00,0x00]
+ ld 1, 0(%r0)
+
+# CHECK: ld 1, 0(31) # encoding: [0xe8,0x3f,0x00,0x00]
+ ld 1, 0(31)
+
+# CHECK: ld 1, 0(31) # encoding: [0xe8,0x3f,0x00,0x00]
+ ld 1, 0(%r31)
+
+# CHECK: ld 1, -32768(2) # encoding: [0xe8,0x22,0x80,0x00]
+ ld 1, -32768(2)
+
+# CHECK: ld 1, 32764(2) # encoding: [0xe8,0x22,0x7f,0xfc]
+ ld 1, 32764(2)
+
+# CHECK: ld 1, 4(2) # encoding: [0xe8,0x22,0x00,0x04]
+ ld 1, 4(2)
+
+# CHECK: ld 1, -4(2) # encoding: [0xe8,0x22,0xff,0xfc]
+ ld 1, -4(2)
+
OpenPOWER on IntegriCloud