summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp133
-rw-r--r--lib/Target/Mips/Disassembler/MipsDisassembler.cpp51
-rw-r--r--lib/Target/Mips/MipsMSAInstrFormats.td5
-rw-r--r--lib/Target/Mips/MipsMSAInstrInfo.td17
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td37
-rw-r--r--test/MC/Mips/msa/test_2rf.s12
6 files changed, 247 insertions, 8 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 3033fef5d8..5b77d87350 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -82,6 +82,10 @@ class MipsAsmParser : public MCTargetAsmParser {
int RegKind);
MipsAsmParser::OperandMatchResultTy
+ parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ int RegKind);
+
+ MipsAsmParser::OperandMatchResultTy
parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
@@ -128,6 +132,18 @@ class MipsAsmParser : public MCTargetAsmParser {
MipsAsmParser::OperandMatchResultTy
parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ MipsAsmParser::OperandMatchResultTy
+ parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
unsigned RegKind);
@@ -199,6 +215,8 @@ class MipsAsmParser : public MCTargetAsmParser {
int matchACRegisterName(StringRef Name);
+ int matchMSA128RegisterName(StringRef Name);
+
int regKindToRegClass(int RegKind);
unsigned getReg(int RC, int RegNo);
@@ -243,7 +261,11 @@ public:
Kind_ACC64DSP,
Kind_LO32DSP,
Kind_HI32DSP,
- Kind_COP2
+ Kind_COP2,
+ Kind_MSA128BRegs,
+ Kind_MSA128HRegs,
+ Kind_MSA128WRegs,
+ Kind_MSA128DRegs
};
private:
@@ -465,6 +487,22 @@ public:
return Kind == k_Register && Reg.Kind == Kind_COP2;
}
+ bool isMSA128BAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
+ }
+
+ bool isMSA128HAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
+ }
+
+ bool isMSA128WAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
+ }
+
+ bool isMSA128DAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
+ }
+
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const {
return StartLoc;
@@ -914,6 +952,18 @@ int MipsAsmParser::matchACRegisterName(StringRef Name) {
return -1;
}
+int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
+ unsigned IntVal;
+
+ if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
+ return -1;
+
+ if (IntVal > 31)
+ return -1;
+
+ return IntVal;
+}
+
int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
int CC;
@@ -921,10 +971,12 @@ int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
if (CC != -1)
return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
: Mips::GPR32RegClassID);
- CC= matchFPURegisterName(Name);
+ CC = matchFPURegisterName(Name);
//TODO: decide about fpu register class
- return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
- : Mips::FGR32RegClassID);
+ if (CC != -1)
+ return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
+ : Mips::FGR32RegClassID);
+ return matchMSA128RegisterName(Name);
}
int MipsAsmParser::regKindToRegClass(int RegKind) {
@@ -940,6 +992,10 @@ int MipsAsmParser::regKindToRegClass(int RegKind) {
case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
+ case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
+ case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
+ case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
+ case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
default :return -1;
}
@@ -1480,6 +1536,51 @@ MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
}
MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ int RegKind) {
+ MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
+ SMLoc S = Parser.getTok().getLoc();
+ std::string RegName;
+
+ if (Parser.getTok().isNot(AsmToken::Dollar))
+ return MatchOperand_NoMatch;
+
+ switch (RegKind) {
+ default:
+ return MatchOperand_ParseFail;
+ case MipsOperand::Kind_MSA128BRegs:
+ case MipsOperand::Kind_MSA128HRegs:
+ case MipsOperand::Kind_MSA128WRegs:
+ case MipsOperand::Kind_MSA128DRegs:
+ break;
+ }
+
+ Parser.Lex(); // Eat the '$'.
+ if (getLexer().getKind() == AsmToken::Identifier)
+ RegName = Parser.getTok().getString().lower();
+ else
+ return MatchOperand_ParseFail;
+
+ int RegNum = matchMSA128RegisterName(RegName);
+
+ if (RegNum < 0 || RegNum > 31)
+ return MatchOperand_ParseFail;
+
+ int RegVal = getReg(regKindToRegClass(Kind), RegNum);
+ if (RegVal == -1)
+ return MatchOperand_ParseFail;
+
+ MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
+ Parser.getTok().getLoc());
+ Op->setRegKind(Kind);
+ Operands.push_back(Op);
+
+ Parser.Lex(); // Eat the register identifier.
+
+ return MatchOperand_Success;
+}
+
+MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
if (!isMips64())
@@ -1619,6 +1720,30 @@ MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return MatchOperand_Success;
}
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSA128BRegs(
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSA128HRegs(
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSA128WRegs(
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSA128DRegs(
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
+}
+
bool MipsAsmParser::searchSymbolAlias(
SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index e2b3fa4182..9fabc3a937 100644
--- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -170,6 +170,21 @@ static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
+
+static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
+
+static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeBranchTarget(MCInst &Inst,
unsigned Offset,
uint64_t Address,
@@ -620,6 +635,42 @@ static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 31)
+ return MCDisassembler::Fail;
+
+ unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 31)
+ return MCDisassembler::Fail;
+
+ unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 31)
+ return MCDisassembler::Fail;
+
+ unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeBranchTarget(MCInst &Inst,
unsigned Offset,
uint64_t Address,
diff --git a/lib/Target/Mips/MipsMSAInstrFormats.td b/lib/Target/Mips/MipsMSAInstrFormats.td
index b011674719..9b63ef02f4 100644
--- a/lib/Target/Mips/MipsMSAInstrFormats.td
+++ b/lib/Target/Mips/MipsMSAInstrFormats.td
@@ -52,8 +52,13 @@ class MSA_2R_FMT<bits<8> major, bits<2> df, bits<6> minor>: MSAInst {
}
class MSA_2RF_FMT<bits<9> major, bits<1> df, bits<6> minor>: MSAInst {
+ bits<5> ws;
+ bits<5> wd;
+
let Inst{25-17} = major;
let Inst{16} = df;
+ let Inst{15-11} = ws;
+ let Inst{10-6} = wd;
let Inst{5-0} = minor;
}
diff --git a/lib/Target/Mips/MipsMSAInstrInfo.td b/lib/Target/Mips/MipsMSAInstrInfo.td
index 740e7f243a..881335fa19 100644
--- a/lib/Target/Mips/MipsMSAInstrInfo.td
+++ b/lib/Target/Mips/MipsMSAInstrInfo.td
@@ -1132,6 +1132,15 @@ class MSA_2RF_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin = NoItinerary> :
MSA_2R_DESC_BASE<instr_asm, OpNode, RCWD, RCWS, itin>;
+class MSA_2RF_RO_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
+ RegisterOperand ROWD, RegisterOperand ROWS = ROWD,
+ InstrItinClass itin = NoItinerary> {
+ dag OutOperandList = (outs ROWD:$wd);
+ dag InOperandList = (ins ROWS:$ws);
+ string AsmString = !strconcat(instr_asm, "\t$wd, $ws");
+ list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws))];
+ InstrItinClass Itinerary = itin;
+}
class MSA_3R_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
RegisterClass RCWD, RegisterClass RCWS = RCWD,
@@ -1612,10 +1621,10 @@ class FCEQ_W_DESC : MSA_3RF_DESC_BASE<"fceq.w", vfsetoeq_v4f32, MSA128W>,
class FCEQ_D_DESC : MSA_3RF_DESC_BASE<"fceq.d", vfsetoeq_v2f64, MSA128D>,
IsCommutable;
-class FCLASS_W_DESC : MSA_2RF_DESC_BASE<"fclass.w", int_mips_fclass_w,
- MSA128W>;
-class FCLASS_D_DESC : MSA_2RF_DESC_BASE<"fclass.d", int_mips_fclass_d,
- MSA128D>;
+class FCLASS_W_DESC : MSA_2RF_RO_DESC_BASE<"fclass.w", int_mips_fclass_w,
+ MSA128WOpnd>;
+class FCLASS_D_DESC : MSA_2RF_RO_DESC_BASE<"fclass.d", int_mips_fclass_d,
+ MSA128DOpnd>;
class FCLE_W_DESC : MSA_3RF_DESC_BASE<"fcle.w", vfsetole_v4f32, MSA128W>;
class FCLE_D_DESC : MSA_3RF_DESC_BASE<"fcle.d", vfsetole_v2f64, MSA128D>;
diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td
index 0b88e0a17c..94bfbf50a6 100644
--- a/lib/Target/Mips/MipsRegisterInfo.td
+++ b/lib/Target/Mips/MipsRegisterInfo.td
@@ -436,6 +436,26 @@ def FCCRegsAsmOperand : MipsAsmRegOperand {
let ParserMethod = "parseFCCRegs";
}
+def MSA128BAsmOperand : MipsAsmRegOperand {
+ let Name = "MSA128BAsm";
+ let ParserMethod = "parseMSA128BRegs";
+}
+
+def MSA128HAsmOperand : MipsAsmRegOperand {
+ let Name = "MSA128HAsm";
+ let ParserMethod = "parseMSA128HRegs";
+}
+
+def MSA128WAsmOperand : MipsAsmRegOperand {
+ let Name = "MSA128WAsm";
+ let ParserMethod = "parseMSA128WRegs";
+}
+
+def MSA128DAsmOperand : MipsAsmRegOperand {
+ let Name = "MSA128DAsm";
+ let ParserMethod = "parseMSA128DRegs";
+}
+
def GPR32Opnd : RegisterOperand<GPR32> {
let ParserMatchClass = GPR32AsmOperand;
}
@@ -501,3 +521,20 @@ def ACC64DSPOpnd : RegisterOperand<ACC64DSP> {
def COP2Opnd : RegisterOperand<COP2> {
let ParserMatchClass = COP2AsmOperand;
}
+
+def MSA128BOpnd : RegisterOperand<MSA128B> {
+ let ParserMatchClass = MSA128BAsmOperand;
+}
+
+def MSA128HOpnd : RegisterOperand<MSA128H> {
+ let ParserMatchClass = MSA128HAsmOperand;
+}
+
+def MSA128WOpnd : RegisterOperand<MSA128W> {
+ let ParserMatchClass = MSA128WAsmOperand;
+}
+
+def MSA128DOpnd : RegisterOperand<MSA128D> {
+ let ParserMatchClass = MSA128DAsmOperand;
+}
+
diff --git a/test/MC/Mips/msa/test_2rf.s b/test/MC/Mips/msa/test_2rf.s
new file mode 100644
index 0000000000..7f80db7cae
--- /dev/null
+++ b/test/MC/Mips/msa/test_2rf.s
@@ -0,0 +1,12 @@
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32r2 -mattr=+msa -arch=mips | FileCheck %s
+#
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -mattr=+msa -arch=mips -filetype=obj -o - | llvm-objdump -d -triple=mipsel-unknown-linux -mattr=+msa -arch=mips - | FileCheck %s -check-prefix=CHECKOBJDUMP
+#
+# CHECK: fclass.w $w26, $w12 # encoding: [0x7b,0x20,0x66,0x9e]
+# CHECK: fclass.d $w24, $w17 # encoding: [0x7b,0x21,0x8e,0x1e]
+
+# CHECKOBJDUMP: fclass.w $w26, $w12
+# CHECKOBJDUMP: fclass.d $w24, $w17
+
+ fclass.w $w26, $w12
+ fclass.d $w24, $w17