diff options
| author | Daniel Sanders <daniel.sanders@imgtec.com> | 2014-05-08 13:02:11 +0000 |
|---|---|---|
| committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2014-05-08 13:02:11 +0000 |
| commit | cdbbe08b0548f904fbb980c144a6d640afdbf005 (patch) | |
| tree | 4b9e22f023bf6a6f6e7e8a1d7f43e09e7b696f60 /llvm/lib | |
| parent | 279b97c130134b4071eff465eef989a9a7ed542f (diff) | |
| download | bcm5719-llvm-cdbbe08b0548f904fbb980c144a6d640afdbf005.tar.gz bcm5719-llvm-cdbbe08b0548f904fbb980c144a6d640afdbf005.zip | |
[mips] Implement l[wd]c3, and s[wd]c3.
Summary:
These instructions were added in MIPS-I, and MIPS-II but were removed in
MIPS-III. Interestingly, GAS continues to accept them when assembling for
MIPS-III.
For the moment, these instructions will follow GAS and accept them for
MIPS-III and newer but this will be tightened up when the invalid-*.s
tests are added.
Depends on D3647
Reviewers: vmedic
Reviewed By: vmedic
Differential Revision: http://reviews.llvm.org/D3648
llvm-svn: 208311
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 19 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrFPU.td | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsRegisterInfo.td | 16 |
3 files changed, 45 insertions, 2 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index d8e783e92c4..b9a0962603f 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -272,11 +272,12 @@ public: /// context). RegKind_CCR = 128, /// CCR RegKind_HWRegs = 256, /// HWRegs + RegKind_COP3 = 512, /// COP3 /// Potentially any (e.g. $1) RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | - RegKind_CCR | RegKind_HWRegs + RegKind_CCR | RegKind_HWRegs | RegKind_COP3 }; private: @@ -428,6 +429,14 @@ private: return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); } + /// Coerce the register to COP3 and return the real register for the + /// current target. + unsigned getCOP3Reg() const { + assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); + unsigned ClassID = Mips::COP3RegClassID; + return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + /// Coerce the register to ACC64DSP and return the real register for the /// current target. unsigned getACC64DSPReg() const { @@ -539,6 +548,11 @@ public: Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); } + void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getCOP3Reg())); + } + void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); @@ -750,6 +764,9 @@ public: bool isCOP2AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; } + bool isCOP3AsmReg() const { + return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; + } bool isMSA128AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; } diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td index c107681cf3f..772ec7b7681 100644 --- a/llvm/lib/Target/Mips/MipsInstrFPU.td +++ b/llvm/lib/Target/Mips/MipsInstrFPU.td @@ -387,12 +387,22 @@ def LDC1 : MMRel, LW_FT<"ldc1", AFGR64Opnd, II_LDC1, load>, LW_FM<0x35>, def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, II_SDC1, store>, LW_FM<0x3d>, ISA_MIPS2, FGR_32; -/// Cop2 Memory Instructions +// Cop2 Memory Instructions +// FIXME: These aren't really FPU instructions and as such don't belong in this +// file 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>, ISA_MIPS2; def SDC2 : SW_FT<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>, ISA_MIPS2; +// Cop3 Memory Instructions +// FIXME: These aren't really FPU instructions and as such don't belong in this +// file +def LWC3 : LW_FT<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>; +def SWC3 : SW_FT<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>; +def LDC3 : LW_FT<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>, ISA_MIPS2; +def SDC3 : SW_FT<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>, ISA_MIPS2; + // Indexed loads and stores. // Base register + offset register addressing mode (indicated by "x" in the // instruction mnemonic) is disallowed under NaCl. diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index 834e6c5fc7b..875a596eb4a 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -205,6 +205,10 @@ let Namespace = "Mips" in { foreach I = 0-31 in def COP2#I : MipsReg<#I, ""#I>; + // COP3 registers. + foreach I = 0-31 in + def COP3#I : MipsReg<#I, ""#I>; + // PC register def PC : Register<"pc">; @@ -387,6 +391,10 @@ def DSPCC : RegisterClass<"Mips", [v4i8, v2i16], 32, (add DSPCCond)>; def COP2 : RegisterClass<"Mips", [i32], 32, (sequence "COP2%u", 0, 31)>, Unallocatable; +// Coprocessor 3 registers. +def COP3 : RegisterClass<"Mips", [i32], 32, (sequence "COP3%u", 0, 31)>, + Unallocatable; + // Octeon multiplier and product registers def OCTEON_MPL : RegisterClass<"Mips", [i64], 64, (add MPL0, MPL1, MPL2)>, Unallocatable; @@ -484,6 +492,10 @@ def COP2AsmOperand : MipsAsmRegOperand { let Name = "COP2AsmReg"; } +def COP3AsmOperand : MipsAsmRegOperand { + let Name = "COP3AsmReg"; +} + def HWRegsOpnd : RegisterOperand<HWRegs> { let ParserMatchClass = HWRegsAsmOperand; } @@ -524,6 +536,10 @@ def COP2Opnd : RegisterOperand<COP2> { let ParserMatchClass = COP2AsmOperand; } +def COP3Opnd : RegisterOperand<COP3> { + let ParserMatchClass = COP3AsmOperand; +} + def MSA128BOpnd : RegisterOperand<MSA128B> { let ParserMatchClass = MSA128AsmOperand; } |

