This patch implements parsing of mips FCC register operands. The example instructions...
authorVladimir Medic <Vladimir.Medic@imgtec.com>
Tue, 30 Jul 2013 10:12:14 +0000 (10:12 +0000)
committerVladimir Medic <Vladimir.Medic@imgtec.com>
Tue, 30 Jul 2013 10:12:14 +0000 (10:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187410 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/MipsCondMov.td
lib/Target/Mips/MipsInstrFPU.td
lib/Target/Mips/MipsRegisterInfo.td
test/MC/Mips/mips-fpu-instructions.s

index 33c73379a4f231e7e10e48818a94b3ef5b0b1c79..7e7b39bb5aa5ad20e0b537d9743e08cf3705830f 100644 (file)
@@ -111,6 +111,9 @@ class MipsAsmParser : public MCTargetAsmParser {
   MipsAsmParser::OperandMatchResultTy
   parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
 
+  MipsAsmParser::OperandMatchResultTy
+  parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
   bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                          unsigned RegKind);
 
@@ -219,7 +222,8 @@ public:
     Kind_FGR32Regs,
     Kind_FGR64Regs,
     Kind_AFGR64Regs,
-    Kind_CCRRegs
+    Kind_CCRRegs,
+    Kind_FCCRegs
   };
 
 private:
@@ -402,6 +406,10 @@ public:
     return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
   }
 
+  bool isFCCRegsAsm() const {
+    return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
+  }
+
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const {
     return StartLoc;
@@ -1326,6 +1334,39 @@ MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
 }
 
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // If the first token is not '$' we have an error.
+  if (Parser.getTok().isNot(AsmToken::Dollar))
+    return MatchOperand_NoMatch;
+
+  SMLoc S = Parser.getTok().getLoc();
+  Parser.Lex(); // Eat the '$'
+
+  const AsmToken &Tok = Parser.getTok(); // Get next token.
+
+  if (Tok.isNot(AsmToken::Identifier))
+    return MatchOperand_NoMatch;
+
+  if (!Tok.getIdentifier().startswith("fcc"))
+    return MatchOperand_NoMatch;
+
+  StringRef NumString = Tok.getIdentifier().substr(3);
+
+  unsigned IntVal;
+  if (NumString.getAsInteger(10, IntVal))
+    return MatchOperand_NoMatch;
+
+  unsigned Reg = matchRegisterByNumber(IntVal, Mips::FCCRegClassID);
+
+  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
+  Op->setRegKind(MipsOperand::Kind_FCCRegs);
+  Operands.push_back(Op);
+
+  Parser.Lex(); // Eat the register number.
+  return MatchOperand_Success;
+}
+
 bool MipsAsmParser::searchSymbolAlias(
     SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
 
index 607c2a9e235a0ee1613066af5129218757fc8dae..ce91575f2936433028b836f829df864382c5bd1d 100644 (file)
@@ -34,18 +34,20 @@ class CMov_I_F_FT<string opstr, RegisterOperand CRC, RegisterOperand DRC,
 // cond:float, data:int
 class CMov_F_I_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
                   SDPatternOperator OpNode = null_frag> :
-  InstSE<(outs RC:$rd), (ins RC:$rs, FCC:$fcc, RC:$F),
+  InstSE<(outs RC:$rd), (ins RC:$rs, FCCRegsOpnd:$fcc, RC:$F),
          !strconcat(opstr, "\t$rd, $rs, $fcc"),
-         [(set RC:$rd, (OpNode RC:$rs, FCC:$fcc, RC:$F))], Itin, FrmFR> {
+         [(set RC:$rd, (OpNode RC:$rs, FCCRegsOpnd:$fcc, RC:$F))],
+         Itin, FrmFR> {
   let Constraints = "$F = $rd";
 }
 
 // cond:float, data:float
-class CMov_F_F_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class CMov_F_F_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
                   SDPatternOperator OpNode = null_frag> :
-  InstSE<(outs RC:$fd), (ins RC:$fs, FCC:$fcc, RC:$F),
+  InstSE<(outs RC:$fd), (ins RC:$fs, FCCRegsOpnd:$fcc, RC:$F),
          !strconcat(opstr, "\t$fd, $fs, $fcc"),
-         [(set RC:$fd, (OpNode RC:$fs, FCC:$fcc, RC:$F))], Itin, FrmFR> {
+         [(set RC:$fd, (OpNode RC:$fs, FCCRegsOpnd:$fcc, RC:$F))],
+         Itin, FrmFR> {
   let Constraints = "$F = $fd";
 }
 
@@ -183,22 +185,22 @@ def MOVF_I64 : CMov_F_I_FT<"movf", CPU64RegsOpnd, IIAlu, MipsCMovFP_F>,
   let DecoderNamespace = "Mips64";
 }
 
-def MOVT_S : CMov_F_F_FT<"movt.s", FGR32, IIFmove, MipsCMovFP_T>,
+def MOVT_S : CMov_F_F_FT<"movt.s", FGR32RegsOpnd, IIFmove, MipsCMovFP_T>,
              CMov_F_F_FM<16, 1>;
-def MOVF_S : CMov_F_F_FT<"movf.s", FGR32, IIFmove, MipsCMovFP_F>,
+def MOVF_S : CMov_F_F_FT<"movf.s", FGR32RegsOpnd, IIFmove, MipsCMovFP_F>,
              CMov_F_F_FM<16, 0>;
 
 let Predicates = [NotFP64bit, HasStdEnc] in {
-  def MOVT_D32 : CMov_F_F_FT<"movt.d", AFGR64, IIFmove, MipsCMovFP_T>,
+  def MOVT_D32 : CMov_F_F_FT<"movt.d", AFGR64RegsOpnd, IIFmove, MipsCMovFP_T>,
                  CMov_F_F_FM<17, 1>;
-  def MOVF_D32 : CMov_F_F_FT<"movf.d", AFGR64, IIFmove, MipsCMovFP_F>,
+  def MOVF_D32 : CMov_F_F_FT<"movf.d", AFGR64RegsOpnd, IIFmove, MipsCMovFP_F>,
                  CMov_F_F_FM<17, 0>;
 }
 let Predicates = [IsFP64bit, HasStdEnc],
     DecoderNamespace = "Mips64" in {
-  def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64, IIFmove, MipsCMovFP_T>,
+  def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64RegsOpnd, IIFmove, MipsCMovFP_T>,
                  CMov_F_F_FM<17, 1>;
-  def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64, IIFmove, MipsCMovFP_F>,
+  def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64RegsOpnd, IIFmove, MipsCMovFP_F>,
                  CMov_F_F_FM<17, 0>;
 }
 
index ce68a28dfcf7cd05356c04eb6bae173d25c9ddf0..c73070bf34a6541ba3958262c453225539210cf6 100644 (file)
@@ -189,9 +189,9 @@ class SWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC,
 
 class BC1F_FT<string opstr, InstrItinClass Itin,
               SDPatternOperator Op = null_frag>  :
-  InstSE<(outs), (ins FCC:$fcc, brtarget:$offset),
+  InstSE<(outs), (ins FCCRegsOpnd:$fcc, brtarget:$offset),
          !strconcat(opstr, "\t$fcc, $offset"),
-         [(MipsFPBrcond Op, FCC:$fcc, bb:$offset)], Itin, FrmFI> {
+         [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin, FrmFI> {
   let isBranch = 1;
   let isTerminator = 1;
   let hasDelaySlot = 1;
index b9b934a4d3af394b127462addaed29a9fc39b11f..640f7d10025e8b0c69d9b3e8ee2b635fb36079b9 100644 (file)
@@ -358,6 +358,11 @@ def FGR32AsmOperand : MipsAsmRegOperand {
   let ParserMethod = "parseFGR32Regs";
 }
 
+def FCCRegsAsmOperand : MipsAsmRegOperand {
+  let Name = "FCCRegsAsm";
+  let ParserMethod = "parseFCCRegs";
+}
+
 def CPURegsOpnd : RegisterOperand<CPURegs> {
   let ParserMatchClass = CPURegsAsmOperand;
 }
@@ -398,4 +403,8 @@ def FGR64RegsOpnd : RegisterOperand<FGR64> {
 
 def FGR32RegsOpnd : RegisterOperand<FGR32> {
   let ParserMatchClass = FGR32AsmOperand;
+}
+
+def FCCRegsOpnd : RegisterOperand<FCC> {
+  let ParserMatchClass = FCCRegsAsmOperand;
 }
\ No newline at end of file
index 256ce4513b7824b31250f6edd016c2938472852f..dc52676433e097e9bc2e9ef7dff19a953d239007 100644 (file)
 # CHECK:  mtc2    $9, $4, 5               # encoding: [0x05,0x20,0x89,0x48]
 # CHECK:  movf    $2, $1, $fcc0           # encoding: [0x01,0x10,0x20,0x00]
 # CHECK:  movt    $2, $1, $fcc0           # encoding: [0x01,0x10,0x21,0x00]
+# CHECK:  movt    $4, $5, $fcc4           # encoding: [0x01,0x20,0xb1,0x00]
+# CHECK:  movf.d  $f4, $f6, $fcc2         # encoding: [0x11,0x31,0x28,0x46]
+# CHECK:  movf.s  $f4, $f6, $fcc5         # encoding: [0x11,0x31,0x14,0x46]
 # CHECK:  luxc1   $f0, $6($5)             # encoding: [0x05,0x00,0xa6,0x4c]
 # CHECK:  suxc1   $f4, $24($5)            # encoding: [0x0d,0x20,0xb8,0x4c]
 
    mtc2    $9, $4, 5
    movf    $2, $1, $fcc0
    movt    $2, $1, $fcc0
+   movt    $4, $5, $fcc4
+   movf.d  $f4, $f6, $fcc2
+   movf.s  $f4, $f6, $fcc5
    luxc1 $f0, $a2($a1)
    suxc1 $f4, $t8($a1)
\ No newline at end of file