[llvm] r191412 - [mips][msa] Direct Object Emission support for the MSA instruction set.

Jack Carter jack.carter at imgtec.com
Wed Sep 25 16:50:44 PDT 2013


Author: jacksprat
Date: Wed Sep 25 18:50:44 2013
New Revision: 191412

URL: http://llvm.org/viewvc/llvm-project?rev=191412&view=rev
Log:
[mips][msa] Direct Object Emission support for the MSA instruction set. 

In more detail, this patch adds the ability to parse, encode and decode MSA registers ($w0-$w31). The format of 2RF instructions (MipsMSAInstrFormat.td) was updated so that we could attach a test case to this patch i.e., the test case parses, encodes and decodes 2 MSA instructions. Following patches will add the remainder of the instructions.

Note that DecodeMSA128BRegisterClass is missing from MipsDisassembler.td because it's not yet required at this stage and having it would cause a compiler warning (unused function).

Patch by Matheus Almeida

Added:
    llvm/trunk/test/MC/Mips/msa/
    llvm/trunk/test/MC/Mips/msa/test_2rf.s
Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
    llvm/trunk/lib/Target/Mips/MipsMSAInstrFormats.td
    llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td

Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=191412&r1=191411&r2=191412&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Wed Sep 25 18:50:44 2013
@@ -82,6 +82,10 @@ class MipsAsmParser : public MCTargetAsm
                          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 MCTargetAsm
   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 MCTargetAsm
 
   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(S
   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(Str
   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
   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
 }
 
 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
   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) {
 

Modified: llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp?rev=191412&r1=191411&r2=191412&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp Wed Sep 25 18:50:44 2013
@@ -170,6 +170,21 @@ static DecodeStatus DecodeLO32DSPRegiste
                                                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,
@@ -619,6 +634,42 @@ static DecodeStatus DecodeLO32DSPRegiste
   Inst.addOperand(MCOperand::CreateReg(Reg));
   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,

Modified: llvm/trunk/lib/Target/Mips/MipsMSAInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMSAInstrFormats.td?rev=191412&r1=191411&r2=191412&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMSAInstrFormats.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsMSAInstrFormats.td Wed Sep 25 18:50:44 2013
@@ -52,8 +52,13 @@ class MSA_2R_FMT<bits<8> major, bits<2>
 }
 
 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;
 }
 

Modified: llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td?rev=191412&r1=191411&r2=191412&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td Wed Sep 25 18:50:44 2013
@@ -1132,6 +1132,15 @@ class MSA_2RF_DESC_BASE<string instr_asm
                         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<"f
 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>;

Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=191412&r1=191411&r2=191412&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Wed Sep 25 18:50:44 2013
@@ -436,6 +436,26 @@ def FCCRegsAsmOperand : MipsAsmRegOperan
   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<ACC64
 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;
+}
+

Added: llvm/trunk/test/MC/Mips/msa/test_2rf.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/msa/test_2rf.s?rev=191412&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/msa/test_2rf.s (added)
+++ llvm/trunk/test/MC/Mips/msa/test_2rf.s Wed Sep 25 18:50:44 2013
@@ -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





More information about the llvm-commits mailing list