[llvm] r224338 - [mips][microMIPS] Implement SWP and LWP instructions

Zoran Jovanovic zoran.jovanovic at imgtec.com
Tue Dec 16 06:59:10 PST 2014


Author: zjovanovic
Date: Tue Dec 16 08:59:10 2014
New Revision: 224338

URL: http://llvm.org/viewvc/llvm-project?rev=224338&view=rev
Log:
[mips][microMIPS] Implement SWP and LWP instructions
Differential Revision: http://reviews.llvm.org/D5667

Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
    llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
    llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
    llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
    llvm/trunk/test/MC/Disassembler/Mips/micromips.txt
    llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt
    llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s

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=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Tue Dec 16 08:59:10 2014
@@ -147,6 +147,9 @@ class MipsAsmParser : public MCTargetAsm
   MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
 
   MipsAsmParser::OperandMatchResultTy
+  parseRegisterPair (OperandVector &Operands);
+
+  MipsAsmParser::OperandMatchResultTy
   parseRegisterList (OperandVector  &Operands);
 
   bool searchSymbolAlias(OperandVector &Operands);
@@ -428,7 +431,8 @@ private:
     k_PhysRegister,  /// A physical register from the Mips namespace
     k_RegisterIndex, /// A register index in one or more RegKind.
     k_Token,         /// A simple token
-    k_RegList        /// A physical register list
+    k_RegList,       /// A physical register list
+    k_RegPair        /// A pair of physical register
   } Kind;
 
 public:
@@ -781,6 +785,13 @@ public:
       Inst.addOperand(MCOperand::CreateReg(RegNo));
   }
 
+  void addRegPairOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 2 && "Invalid number of operands!");
+    unsigned RegNo = getRegPair();
+    Inst.addOperand(MCOperand::CreateReg(RegNo++));
+    Inst.addOperand(MCOperand::CreateReg(RegNo));
+  }
+
   bool isReg() const override {
     // As a special case until we sort out the definition of div/divu, pretend
     // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
@@ -845,6 +856,7 @@ public:
     assert(Kind == k_Token && "Invalid access!");
     return StringRef(Tok.Data, Tok.Length);
   }
+  bool isRegPair() const { return Kind == k_RegPair; }
 
   unsigned getReg() const override {
     // As a special case until we sort out the definition of div/divu, pretend
@@ -886,6 +898,11 @@ public:
     return *(RegList.List);
   }
 
+  unsigned getRegPair() const {
+    assert((Kind == k_RegPair) && "Invalid access!");
+    return RegIdx.Index;
+  }
+
   static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
                                                   MipsAsmParser &Parser) {
     auto Op = make_unique<MipsOperand>(k_Token, Parser);
@@ -995,6 +1012,15 @@ public:
     return Op;
   }
 
+  static std::unique_ptr<MipsOperand>
+  CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
+    auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
+    Op->RegIdx.Index = RegNo;
+    Op->StartLoc = S;
+    Op->EndLoc = E;
+    return Op;
+  }
+
   bool isGPRAsmReg() const {
     return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
   }
@@ -1061,6 +1087,7 @@ public:
     case k_PhysRegister:
     case k_RegisterIndex:
     case k_Token:
+    case k_RegPair:
       break;
     }
   }
@@ -1094,6 +1121,9 @@ public:
         OS << Reg << " ";
       OS <<  ">";
       break;
+    case k_RegPair:
+      OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
+      break;
     }
   }
 }; // class MipsOperand
@@ -2723,6 +2753,22 @@ MipsAsmParser::parseRegisterList(Operand
   return MatchOperand_Success;
 }
 
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
+  MCAsmParser &Parser = getParser();
+
+  SMLoc S = Parser.getTok().getLoc();
+  if (parseAnyRegister(Operands) != MatchOperand_Success)
+    return MatchOperand_ParseFail;
+
+  SMLoc E = Parser.getTok().getLoc();
+  MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
+  unsigned Reg = Op.getGPR32Reg();
+  Operands.pop_back();
+  Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
+  return MatchOperand_Success;
+}
+
 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
 
   MCSymbolRefExpr::VariantKind VK =

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=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp Tue Dec 16 08:59:10 2014
@@ -1222,6 +1222,9 @@ static DecodeStatus DecodeMemMMImm12(MCI
     // fallthrough
   default:
     Inst.addOperand(MCOperand::CreateReg(Reg));
+    if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
+      Inst.addOperand(MCOperand::CreateReg(Reg+1));
+
     Inst.addOperand(MCOperand::CreateReg(Base));
     Inst.addOperand(MCOperand::CreateImm(Offset));
   }

Modified: llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp Tue Dec 16 08:59:10 2014
@@ -262,6 +262,11 @@ printFCCOperand(const MCInst *MI, int op
 }
 
 void MipsInstPrinter::
+printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O) {
+  printRegName(O, MI->getOperand(opNum).getReg());
+}
+
+void MipsInstPrinter::
 printSHFMask(const MCInst *MI, int opNum, raw_ostream &O) {
   llvm_unreachable("TODO");
 }

Modified: llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h (original)
+++ llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h Tue Dec 16 08:59:10 2014
@@ -99,6 +99,7 @@ private:
   void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O);
   void printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O);
   void printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O);
+  void printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O);
   void printSHFMask(const MCInst *MI, int opNum, raw_ostream &O);
 
   bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo,

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp Tue Dec 16 08:59:10 2014
@@ -862,4 +862,11 @@ MipsMCCodeEmitter::getRegisterListOpValu
   return (MI.getNumOperands() - 4);
 }
 
+unsigned
+MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const {
+  return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
+}
+
 #include "MipsGenMCCodeEmitter.inc"

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h Tue Dec 16 08:59:10 2014
@@ -184,6 +184,10 @@ public:
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;
 
+  unsigned getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
+                                  SmallVectorImpl<MCFixup> &Fixups,
+                                  const MCSubtargetInfo &STI) const;
+
   unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
                           const MCSubtargetInfo &STI) const;
 

Modified: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td Tue Dec 16 08:59:10 2014
@@ -148,6 +148,36 @@ class StoreLeftRightMM<string opstr, SDN
   let DecoderMethod = "DecodeMemMMImm12";
 }
 
+/// A register pair used by load/store pair instructions.
+def RegPairAsmOperand : AsmOperandClass {
+  let Name = "RegPair";
+  let ParserMethod = "parseRegisterPair";
+}
+
+def regpair : Operand<i32> {
+  let EncoderMethod = "getRegisterPairOpValue";
+  let ParserMatchClass = RegPairAsmOperand;
+  let PrintMethod = "printRegisterPair";
+  let DecoderMethod = "DecodeRegPairOperand";
+  let MIOperandInfo = (ops GPR32Opnd, GPR32Opnd);
+}
+
+class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary,
+                  ComplexPattern Addr = addr> :
+  InstSE<(outs), (ins regpair:$rt, mem_mm_12:$addr),
+         !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
+  let DecoderMethod = "DecodeMemMMImm12";
+  let mayStore = 1;
+}
+
+class LoadPairMM<string opstr, InstrItinClass Itin = NoItinerary,
+                 ComplexPattern Addr = addr> :
+  InstSE<(outs regpair:$rt), (ins mem_mm_12:$addr),
+          !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
+  let DecoderMethod = "DecodeMemMMImm12";
+  let mayLoad = 1;
+}
+
 class LLBaseMM<string opstr, RegisterOperand RO> :
   InstSE<(outs RO:$rt), (ins mem_mm_12:$addr),
          !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
@@ -555,6 +585,10 @@ let DecoderNamespace = "MicroMips", Pred
   def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>;
   def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>;
 
+  /// Load and Store Pair Instructions
+  def SWP_MM  : StorePairMM<"swp">, LWM_FM_MM<0x9>;
+  def LWP_MM  : LoadPairMM<"lwp">, LWM_FM_MM<0x1>;
+
   /// Move Conditional
   def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd,
                   NoItinerary>, ADD_FM_MM<0, 0x58>;

Modified: llvm/trunk/test/MC/Disassembler/Mips/micromips.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/micromips.txt?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/micromips.txt (original)
+++ llvm/trunk/test/MC/Disassembler/Mips/micromips.txt Tue Dec 16 08:59:10 2014
@@ -343,6 +343,12 @@
 # CHECK: swm32 $16, $17, 8($4)
 0x20 0x44 0xd0 0x08
 
+# CHECK: swp $16, 8($4)
+0x22 0x04 0x90 0x08
+
+# CHECK: lwp $16, 8($4)
+0x22 0x04 0x10 0x08
+
 # CHECK: nop
 0x00 0x00 0x00 0x00
 

Modified: llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt (original)
+++ llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt Tue Dec 16 08:59:10 2014
@@ -343,6 +343,12 @@
 # CHECK: swm32 $16, $17, 8($4)
 0x44 0x20 0x08 0xd0
 
+# CHECK: swp $16, 8($4)
+0x04 0x22  0x08 0x90
+
+# CHECK: lwp $16, 8($4)
+0x04 0x22 0x08 0x10
+
 # CHECK: nop
 0x00 0x00 0x00 0x00
 

Modified: llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s?rev=224338&r1=224337&r2=224338&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s (original)
+++ llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s Tue Dec 16 08:59:10 2014
@@ -31,6 +31,8 @@
 # CHECK-EL: swm32  $16, $17, $18, $19, 8($4)  # encoding: [0x84,0x20,0x08,0xd0]
 # CHECK-EL: lwm16  $16, $17, $ra, 8($sp)      # encoding: [0x12,0x45]
 # CHECK-EL: swm16  $16, $17, $ra, 8($sp)      # encoding: [0x52,0x45]
+# CHECK-EL: swp    $16, 8($4)                 # encoding: [0x04,0x22,0x08,0x90]
+# CHECK-EL: lwp    $16, 8($4)                 # encoding: [0x04,0x22,0x08,0x10]
 #------------------------------------------------------------------------------
 # Big endian
 #------------------------------------------------------------------------------
@@ -56,6 +58,8 @@
 # CHECK-EB: swm32  $16, $17, $18, $19, 8($4) # encoding: [0x20,0x84,0xd0,0x08]
 # CHECK-EB: lwm16  $16, $17, $ra, 8($sp)     # encoding: [0x45,0x12]
 # CHECK-EB: swm16  $16, $17, $ra, 8($sp)     # encoding: [0x45,0x52]
+# CHECK-EB: swp    $16, 8($4)                # encoding: [0x22,0x04,0x90,0x08]
+# CHECK-EB: lwp    $16, 8($4)                # encoding: [0x22,0x04,0x10,0x08]
      lb     $5, 8($4)
      lbu    $6, 8($4)
      lh     $2, 8($4)
@@ -78,3 +82,5 @@
      swm32  $16 - $19, 8($4)
      lwm16  $16, $17, $ra, 8($sp)
      swm16  $16, $17, $ra, 8($sp)
+     swp    $16, 8($4)
+     lwp    $16, 8($4)





More information about the llvm-commits mailing list