[mips][msa] Direct Object Emission support for CTCMSA and CFCMSA.
authorMatheus Almeida <matheus.almeida@imgtec.com>
Mon, 21 Oct 2013 12:26:50 +0000 (12:26 +0000)
committerMatheus Almeida <matheus.almeida@imgtec.com>
Mon, 21 Oct 2013 12:26:50 +0000 (12:26 +0000)
These instructions are logically related as they allow read/write of MSA control registers.
Currently MSA control registers are emitted by number but hopefully that will change as soon
as GAS starts accepting them by name as that would make the assembly easier to read.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193078 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/Disassembler/MipsDisassembler.cpp
lib/Target/Mips/MipsMSAInstrFormats.td
lib/Target/Mips/MipsMSAInstrInfo.td
lib/Target/Mips/MipsRegisterInfo.td
test/MC/Mips/msa/test_ctrlregs.s [new file with mode: 0644]

index 16260857c247a1f59bf9644262d60e7588a63a4f..fa7f7c5cdca7b8c3322f325d0f0479fef845e89f 100644 (file)
@@ -91,6 +91,10 @@ class MipsAsmParser : public MCTargetAsmParser {
   parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                int RegKind);
 
+  MipsAsmParser::OperandMatchResultTy
+  parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+                   int RegKind);
+
   MipsAsmParser::OperandMatchResultTy
   parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
 
@@ -150,6 +154,9 @@ class MipsAsmParser : public MCTargetAsmParser {
   MipsAsmParser::OperandMatchResultTy
   parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
 
+  MipsAsmParser::OperandMatchResultTy
+  parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
   MipsAsmParser::OperandMatchResultTy
   parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
 
@@ -228,6 +235,8 @@ class MipsAsmParser : public MCTargetAsmParser {
 
   int matchMSA128RegisterName(StringRef Name);
 
+  int matchMSA128CtrlRegisterName(StringRef Name);
+
   int regKindToRegClass(int RegKind);
 
   unsigned getReg(int RC, int RegNo);
@@ -282,7 +291,8 @@ public:
     Kind_MSA128BRegs,
     Kind_MSA128HRegs,
     Kind_MSA128WRegs,
-    Kind_MSA128DRegs
+    Kind_MSA128DRegs,
+    Kind_MSA128CtrlRegs
   };
 
 private:
@@ -521,6 +531,10 @@ public:
     return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
   }
 
+  bool isMSA128CRAsm() const {
+    return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
+  }
+
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const {
     return StartLoc;
@@ -982,6 +996,23 @@ int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
   return IntVal;
 }
 
+int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
+  int CC;
+
+  CC = StringSwitch<unsigned>(Name)
+    .Case("msair",      0)
+    .Case("msacsr",     1)
+    .Case("msaaccess",  2)
+    .Case("msasave",    3)
+    .Case("msamodify",  4)
+    .Case("msarequest", 5)
+    .Case("msamap",     6)
+    .Case("msaunmap",   7)
+    .Default(-1);
+
+  return CC;
+}
+
 int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
 
   int CC;
@@ -1014,6 +1045,7 @@ int MipsAsmParser::regKindToRegClass(int RegKind) {
   case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
   case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
   case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
+  case MipsOperand::Kind_MSA128CtrlRegs: return Mips::MSACtrlRegClassID;
   default :return -1;
   }
 
@@ -1714,6 +1746,45 @@ MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
   return MatchOperand_Success;
 }
 
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+                                int RegKind) {
+  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
+
+  if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
+    return MatchOperand_NoMatch;
+
+  if (Parser.getTok().isNot(AsmToken::Dollar))
+    return MatchOperand_ParseFail;
+
+  SMLoc S = Parser.getTok().getLoc();
+
+  Parser.Lex(); // Eat the '$' symbol.
+
+  int RegNum = -1;
+  if (getLexer().getKind() == AsmToken::Identifier)
+    RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
+  else if (getLexer().getKind() == AsmToken::Integer)
+    RegNum = Parser.getTok().getIntVal();
+  else
+    return MatchOperand_ParseFail;
+
+  if (RegNum < 0 || RegNum > 7)
+    return MatchOperand_ParseFail;
+
+  int RegVal = getReg(regKindToRegClass(Kind), RegNum);
+  if (RegVal == -1)
+    return MatchOperand_ParseFail;
+
+  MipsOperand *RegOp = MipsOperand::CreateReg(RegVal, S,
+                                              Parser.getTok().getLoc());
+  RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
+  Operands.push_back(RegOp);
+  Parser.Lex(); // Eat the register identifier.
+
+  return MatchOperand_Success;
+}
+
 MipsAsmParser::OperandMatchResultTy
 MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
 
@@ -1878,6 +1949,12 @@ MipsAsmParser::parseMSA128DRegs(
   return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
 }
 
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSA128CtrlRegs(
+                             SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+  return parseMSACtrlRegs(Operands, (int) MipsOperand::Kind_MSA128CtrlRegs);
+}
+
 bool MipsAsmParser::searchSymbolAlias(
     SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
 
index c8d0d882999db5bd734e9bff359acc7bda53947a..da495642961761e47ac46ab1de152ac1c353664d 100644 (file)
@@ -190,6 +190,11 @@ static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
                                                uint64_t Address,
                                                const void *Decoder);
 
+static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
+                                               unsigned RegNo,
+                                               uint64_t Address,
+                                               const void *Decoder);
+
 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
                                        unsigned Offset,
                                        uint64_t Address,
@@ -688,6 +693,18 @@ static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
+                                               unsigned RegNo,
+                                               uint64_t Address,
+                                               const void *Decoder) {
+  if (RegNo > 7)
+    return MCDisassembler::Fail;
+
+  unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
+  Inst.addOperand(MCOperand::CreateReg(Reg));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
                                        unsigned Offset,
                                        uint64_t Address,
index c9b37451701b197b90d3538a90b84fdaf4711254..8fe4dbca569dce02dc7b6fbd53969c414184bdd6 100644 (file)
@@ -150,6 +150,26 @@ class MSA_ELM_FMT<bits<10> major, bits<6> minor>: MSAInst {
   let Inst{5-0} = minor;
 }
 
+class MSA_ELM_CFCMSA_FMT<bits<10> major, bits<6> minor>: MSAInst {
+  bits<5> rd;
+  bits<5> cs;
+
+  let Inst{25-16} = major;
+  let Inst{15-11} = cs;
+  let Inst{10-6} = rd;
+  let Inst{5-0} = minor;
+}
+
+class MSA_ELM_CTCMSA_FMT<bits<10> major, bits<6> minor>: MSAInst {
+  bits<5> rs;
+  bits<5> cd;
+
+  let Inst{25-16} = major;
+  let Inst{15-11} = rs;
+  let Inst{10-6} = cd;
+  let Inst{5-0} = minor;
+}
+
 class MSA_ELM_B_FMT<bits<4> major, bits<6> minor>: MSAInst {
   bits<4> n;
   bits<5> ws;
index 23dd393591550c112f97e5be3ab8b6ad8cd725b4..09c06bcd8ab831fc0c2904493798e4acf91f085b 100644 (file)
@@ -470,7 +470,7 @@ class CEQI_H_ENC : MSA_I5_FMT<0b000, 0b01, 0b000111>;
 class CEQI_W_ENC : MSA_I5_FMT<0b000, 0b10, 0b000111>;
 class CEQI_D_ENC : MSA_I5_FMT<0b000, 0b11, 0b000111>;
 
-class CFCMSA_ENC : MSA_ELM_FMT<0b0001111110, 0b011001>;
+class CFCMSA_ENC : MSA_ELM_CFCMSA_FMT<0b0001111110, 0b011001>;
 
 class CLE_S_B_ENC : MSA_3R_FMT<0b100, 0b00, 0b001111>;
 class CLE_S_H_ENC : MSA_3R_FMT<0b100, 0b01, 0b001111>;
@@ -520,7 +520,7 @@ class COPY_U_B_ENC : MSA_ELM_COPY_B_FMT<0b0011, 0b011001>;
 class COPY_U_H_ENC : MSA_ELM_COPY_H_FMT<0b0011, 0b011001>;
 class COPY_U_W_ENC : MSA_ELM_COPY_W_FMT<0b0011, 0b011001>;
 
-class CTCMSA_ENC : MSA_ELM_FMT<0b0000111110, 0b011001>;
+class CTCMSA_ENC : MSA_ELM_CTCMSA_FMT<0b0000111110, 0b011001>;
 
 class DIV_S_B_ENC : MSA_3R_FMT<0b100, 0b00, 0b010010>;
 class DIV_S_H_ENC : MSA_3R_FMT<0b100, 0b01, 0b010010>;
@@ -1582,8 +1582,8 @@ class CEQI_D_DESC : MSA_I5_DESC_BASE<"ceqi.d", vseteq_v2i64, vsplati64_simm5,
                                      MSA128DOpnd>;
 
 class CFCMSA_DESC {
-  dag OutOperandList = (outs GPR32:$rd);
-  dag InOperandList = (ins MSACtrl:$cs);
+  dag OutOperandList = (outs GPR32Opnd:$rd);
+  dag InOperandList = (ins MSA128CROpnd:$cs);
   string AsmString = "cfcmsa\t$rd, $cs";
   InstrItinClass Itinerary = NoItinerary;
   bit hasSideEffects = 1;
@@ -1666,7 +1666,7 @@ class COPY_FD_PSEUDO_DESC : MSA_COPY_PSEUDO_BASE<vector_extract, v2f64, FGR64,
 
 class CTCMSA_DESC {
   dag OutOperandList = (outs);
-  dag InOperandList = (ins MSACtrl:$cd, GPR32:$rs);
+  dag InOperandList = (ins MSA128CROpnd:$cd, GPR32Opnd:$rs);
   string AsmString = "ctcmsa\t$cd, $rs";
   InstrItinClass Itinerary = NoItinerary;
   bit hasSideEffects = 1;
index 9ccad52c944c4d422ebf75fd3db53eae8ebdf4f2..3173d0927af1b222b10e3ff86d53fc7f4a3cd8d7 100644 (file)
@@ -237,14 +237,14 @@ let Namespace = "Mips" in {
                                             DSPOutFlag23]>;
 
   // MSA-ASE control registers.
-  def MSAIR : Register<"0">;
-  def MSACSR : Register<"1">;
-  def MSAAccess : Register<"2">;
-  def MSASave : Register<"3">;
-  def MSAModify : Register<"4">;
-  def MSARequest : Register<"5">;
-  def MSAMap : Register<"6">;
-  def MSAUnmap : Register<"7">;
+  def MSAIR      : MipsReg<0, "0">;
+  def MSACSR     : MipsReg<1, "1">;
+  def MSAAccess  : MipsReg<2, "2">;
+  def MSASave    : MipsReg<3, "3">;
+  def MSAModify  : MipsReg<4, "4">;
+  def MSARequest : MipsReg<5, "5">;
+  def MSAMap     : MipsReg<6, "6">;
+  def MSAUnmap   : MipsReg<7, "7">;
 }
 
 //===----------------------------------------------------------------------===//
@@ -456,6 +456,11 @@ def MSA128DAsmOperand : MipsAsmRegOperand {
   let ParserMethod = "parseMSA128DRegs";
 }
 
+def MSA128CRAsmOperand : MipsAsmRegOperand {
+  let Name = "MSA128CRAsm";
+  let ParserMethod = "parseMSA128CtrlRegs";
+}
+
 def GPR32Opnd : RegisterOperand<GPR32> {
   let ParserMatchClass = GPR32AsmOperand;
 }
@@ -538,3 +543,7 @@ def MSA128DOpnd : RegisterOperand<MSA128D> {
   let ParserMatchClass = MSA128DAsmOperand;
 }
 
+def MSA128CROpnd : RegisterOperand<MSACtrl> {
+  let ParserMatchClass = MSA128CRAsmOperand;
+}
+
diff --git a/test/MC/Mips/msa/test_ctrlregs.s b/test/MC/Mips/msa/test_ctrlregs.s
new file mode 100644 (file)
index 0000000..f8f4f9e
--- /dev/null
@@ -0,0 +1,105 @@
+# 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:  cfcmsa       $1, $0                  # encoding: [0x78,0x7e,0x00,0x59]
+#CHECK:  cfcmsa       $1, $0                  # encoding: [0x78,0x7e,0x00,0x59]
+#CHECK:  cfcmsa       $2, $1                  # encoding: [0x78,0x7e,0x08,0x99]
+#CHECK:  cfcmsa       $2, $1                  # encoding: [0x78,0x7e,0x08,0x99]
+#CHECK:  cfcmsa       $3, $2                  # encoding: [0x78,0x7e,0x10,0xd9]
+#CHECK:  cfcmsa       $3, $2                  # encoding: [0x78,0x7e,0x10,0xd9]
+#CHECK:  cfcmsa       $4, $3                  # encoding: [0x78,0x7e,0x19,0x19]
+#CHECK:  cfcmsa       $4, $3                  # encoding: [0x78,0x7e,0x19,0x19]
+#CHECK:  cfcmsa       $5, $4                  # encoding: [0x78,0x7e,0x21,0x59]
+#CHECK:  cfcmsa       $5, $4                  # encoding: [0x78,0x7e,0x21,0x59]
+#CHECK:  cfcmsa       $6, $5                  # encoding: [0x78,0x7e,0x29,0x99]
+#CHECK:  cfcmsa       $6, $5                  # encoding: [0x78,0x7e,0x29,0x99]
+#CHECK:  cfcmsa       $7, $6                  # encoding: [0x78,0x7e,0x31,0xd9]
+#CHECK:  cfcmsa       $7, $6                  # encoding: [0x78,0x7e,0x31,0xd9]
+#CHECK:  cfcmsa       $8, $7                  # encoding: [0x78,0x7e,0x3a,0x19]
+#CHECK:  cfcmsa       $8, $7                  # encoding: [0x78,0x7e,0x3a,0x19]
+
+#CHECK:  ctcmsa       $0, $1                  # encoding: [0x78,0x3e,0x08,0x19]
+#CHECK:  ctcmsa       $0, $1                  # encoding: [0x78,0x3e,0x08,0x19]
+#CHECK:  ctcmsa       $1, $2                  # encoding: [0x78,0x3e,0x10,0x59]
+#CHECK:  ctcmsa       $1, $2                  # encoding: [0x78,0x3e,0x10,0x59]
+#CHECK:  ctcmsa       $2, $3                  # encoding: [0x78,0x3e,0x18,0x99]
+#CHECK:  ctcmsa       $2, $3                  # encoding: [0x78,0x3e,0x18,0x99]
+#CHECK:  ctcmsa       $3, $4                  # encoding: [0x78,0x3e,0x20,0xd9]
+#CHECK:  ctcmsa       $3, $4                  # encoding: [0x78,0x3e,0x20,0xd9]
+#CHECK:  ctcmsa       $4, $5                  # encoding: [0x78,0x3e,0x29,0x19]
+#CHECK:  ctcmsa       $4, $5                  # encoding: [0x78,0x3e,0x29,0x19]
+#CHECK:  ctcmsa       $5, $6                  # encoding: [0x78,0x3e,0x31,0x59]
+#CHECK:  ctcmsa       $5, $6                  # encoding: [0x78,0x3e,0x31,0x59]
+#CHECK:  ctcmsa       $6, $7                  # encoding: [0x78,0x3e,0x39,0x99]
+#CHECK:  ctcmsa       $6, $7                  # encoding: [0x78,0x3e,0x39,0x99]
+#CHECK:  ctcmsa       $7, $8                  # encoding: [0x78,0x3e,0x41,0xd9]
+#CHECK:  ctcmsa       $7, $8                  # encoding: [0x78,0x3e,0x41,0xd9]
+
+#CHECKOBJDUMP:  cfcmsa       $1, $0
+#CHECKOBJDUMP:  cfcmsa       $1, $0
+#CHECKOBJDUMP:  cfcmsa       $2, $1
+#CHECKOBJDUMP:  cfcmsa       $2, $1
+#CHECKOBJDUMP:  cfcmsa       $3, $2
+#CHECKOBJDUMP:  cfcmsa       $3, $2
+#CHECKOBJDUMP:  cfcmsa       $4, $3
+#CHECKOBJDUMP:  cfcmsa       $4, $3
+#CHECKOBJDUMP:  cfcmsa       $5, $4
+#CHECKOBJDUMP:  cfcmsa       $5, $4
+#CHECKOBJDUMP:  cfcmsa       $6, $5
+#CHECKOBJDUMP:  cfcmsa       $6, $5
+#CHECKOBJDUMP:  cfcmsa       $7, $6
+#CHECKOBJDUMP:  cfcmsa       $7, $6
+#CHECKOBJDUMP:  cfcmsa       $8, $7
+#CHECKOBJDUMP:  cfcmsa       $8, $7
+
+#CHECKOBJDUMP:  ctcmsa       $0, $1
+#CHECKOBJDUMP:  ctcmsa       $0, $1
+#CHECKOBJDUMP:  ctcmsa       $1, $2
+#CHECKOBJDUMP:  ctcmsa       $1, $2
+#CHECKOBJDUMP:  ctcmsa       $2, $3
+#CHECKOBJDUMP:  ctcmsa       $2, $3
+#CHECKOBJDUMP:  ctcmsa       $3, $4
+#CHECKOBJDUMP:  ctcmsa       $3, $4
+#CHECKOBJDUMP:  ctcmsa       $4, $5
+#CHECKOBJDUMP:  ctcmsa       $4, $5
+#CHECKOBJDUMP:  ctcmsa       $5, $6
+#CHECKOBJDUMP:  ctcmsa       $5, $6
+#CHECKOBJDUMP:  ctcmsa       $6, $7
+#CHECKOBJDUMP:  ctcmsa       $6, $7
+#CHECKOBJDUMP:  ctcmsa       $7, $8
+#CHECKOBJDUMP:  ctcmsa       $7, $8
+
+cfcmsa       $1, $msair
+cfcmsa       $1, $0
+cfcmsa       $2, $msacsr
+cfcmsa       $2, $1
+cfcmsa       $3, $msaaccess
+cfcmsa       $3, $2
+cfcmsa       $4, $msasave
+cfcmsa       $4, $3
+cfcmsa       $5, $msamodify
+cfcmsa       $5, $4
+cfcmsa       $6, $msarequest
+cfcmsa       $6, $5
+cfcmsa       $7, $msamap
+cfcmsa       $7, $6
+cfcmsa       $8, $msaunmap
+cfcmsa       $8, $7
+
+ctcmsa       $msair, $1
+ctcmsa       $0, $1
+ctcmsa       $msacsr, $2
+ctcmsa       $1, $2
+ctcmsa       $msaaccess, $3
+ctcmsa       $2, $3
+ctcmsa       $msasave, $4
+ctcmsa       $3, $4
+ctcmsa       $msamodify, $5
+ctcmsa       $4, $5
+ctcmsa       $msarequest, $6
+ctcmsa       $5, $6
+ctcmsa       $msamap, $7
+ctcmsa       $6, $7
+ctcmsa       $msaunmap, $8
+ctcmsa       $7, $8