aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Medic <Vladimir.Medic@imgtec.com>2013-09-16 10:29:42 +0000
committerVladimir Medic <Vladimir.Medic@imgtec.com>2013-09-16 10:29:42 +0000
commite925f7dbbf497412cd0cc3f67b9b96fed0cc3712 (patch)
treed437b605c6c2a28eebc0587ab88f8342319ef300
parent9bc7603750926c15648dae0d31a5451861a0d11e (diff)
downloadexternal_llvm-e925f7dbbf497412cd0cc3f67b9b96fed0cc3712.zip
external_llvm-e925f7dbbf497412cd0cc3f67b9b96fed0cc3712.tar.gz
external_llvm-e925f7dbbf497412cd0cc3f67b9b96fed0cc3712.tar.bz2
This patch implements Mips load/store instructions from/to coprocessor 2. Test cases are added.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190780 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp36
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td8
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td17
-rw-r--r--test/MC/Mips/mips-fpu-instructions.s8
4 files changed, 68 insertions, 1 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index c4ce4ff..3033fef 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -125,6 +125,9 @@ class MipsAsmParser : public MCTargetAsmParser {
MipsAsmParser::OperandMatchResultTy
parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ MipsAsmParser::OperandMatchResultTy
+ parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
unsigned RegKind);
@@ -239,7 +242,8 @@ public:
Kind_FCCRegs,
Kind_ACC64DSP,
Kind_LO32DSP,
- Kind_HI32DSP
+ Kind_HI32DSP,
+ Kind_COP2
};
private:
@@ -457,6 +461,10 @@ public:
return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
}
+ bool isCOP2Asm() const {
+ return Kind == k_Register && Reg.Kind == Kind_COP2;
+ }
+
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const {
return StartLoc;
@@ -1585,6 +1593,32 @@ MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return MatchOperand_Success;
}
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseCOP2(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::Integer))
+ return MatchOperand_NoMatch;
+
+ unsigned IntVal = Tok.getIntVal();
+
+ unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
+
+ MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
+ Op->setRegKind(MipsOperand::Kind_COP2);
+ Operands.push_back(Op);
+
+ Parser.Lex(); // Eat the register number.
+ return MatchOperand_Success;
+}
+
bool MipsAsmParser::searchSymbolAlias(
SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index 7aa080f..9f7ce9a 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -372,6 +372,14 @@ let Predicates = [NotFP64bit, HasStdEnc] in {
def SDC1 : SW_FT<"sdc1", AFGR64Opnd, IIFStore, store>, LW_FM<0x3d>;
}
+/// Cop2 Memory Instructions
+let Predicates = [HasStdEnc] in {
+ def LWC2 : LW_FT<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>;
+ def SWC2 : SW_FT<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>;
+ def LDC2 : LW_FT<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>;
+ def SDC2 : SW_FT<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>;
+}
+
// Indexed loads and stores.
let Predicates = [HasFPIdx, HasStdEnc] in {
def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, IIFLoad, load>, LWXC1_FM<0>;
diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td
index cef5ebf..0b88e0a 100644
--- a/lib/Target/Mips/MipsRegisterInfo.td
+++ b/lib/Target/Mips/MipsRegisterInfo.td
@@ -201,6 +201,10 @@ let Namespace = "Mips" in {
foreach I = 0-7 in
def FCC#I : MipsReg<#I, "fcc"#I>;
+ // COP2 registers.
+ foreach I = 0-31 in
+ def COP2#I : MipsReg<#I, ""#I>;
+
// PC register
def PC : Register<"pc">;
@@ -368,6 +372,10 @@ def ACC64DSP : RegisterClass<"Mips", [untyped], 64, (sequence "AC%u", 0, 3)> {
def DSPCC : RegisterClass<"Mips", [v4i8, v2i16], 32, (add DSPCCond)>;
+// Coprocessor 2 registers.
+def COP2 : RegisterClass<"Mips", [i32], 32, (sequence "COP2%u", 0, 31)>,
+ Unallocatable;
+
// Register Operands.
class MipsAsmRegOperand : AsmOperandClass {
@@ -449,6 +457,11 @@ def HWRegsAsmOperand : MipsAsmRegOperand {
let ParserMethod = "parseHWRegs";
}
+def COP2AsmOperand : MipsAsmRegOperand {
+ let Name = "COP2Asm";
+ let ParserMethod = "parseCOP2";
+}
+
def HWRegsOpnd : RegisterOperand<HWRegs> {
let ParserMatchClass = HWRegsAsmOperand;
}
@@ -484,3 +497,7 @@ def HI32DSPOpnd : RegisterOperand<HI32DSP> {
def ACC64DSPOpnd : RegisterOperand<ACC64DSP> {
let ParserMatchClass = ACC64DSPAsmOperand;
}
+
+def COP2Opnd : RegisterOperand<COP2> {
+ let ParserMatchClass = COP2AsmOperand;
+}
diff --git a/test/MC/Mips/mips-fpu-instructions.s b/test/MC/Mips/mips-fpu-instructions.s
index eb1f6be..be0a900 100644
--- a/test/MC/Mips/mips-fpu-instructions.s
+++ b/test/MC/Mips/mips-fpu-instructions.s
@@ -169,6 +169,10 @@
# CHECK: swxc1 $f26, $18($22) # encoding: [0x08,0xd0,0xd2,0x4e]
# CHECK: mfhc1 $17, $f4 # encoding: [0x00,0x20,0x71,0x44]
# CHECK: mthc1 $17, $f6 # encoding: [0x00,0x30,0xf1,0x44]
+# CHECK: swc2 $4, 16($sp) # encoding: [0x10,0x00,0xa4,0xeb]
+# CHECK: sdc2 $4, 16($sp) # encoding: [0x10,0x00,0xa4,0xfb]
+# CHECK: lwc2 $11, 12($ra) # encoding: [0x0c,0x00,0xeb,0xcb]
+# CHECK: ldc2 $11, 12($ra) # encoding: [0x0c,0x00,0xeb,0xdb]
cfc1 $a2,$0
ctc1 $10,$31
@@ -200,3 +204,7 @@
swxc1 $f26, $s2($s6)
mfhc1 $17, $f4
mthc1 $17, $f6
+ swc2 $4, 16($sp)
+ sdc2 $4, 16($sp)
+ lwc2 $11, 12($ra)
+ ldc2 $11, 12($ra)