summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips
diff options
context:
space:
mode:
authorZlatko Buljan <Zlatko.Buljan@imgtec.com>2016-03-31 08:51:24 +0000
committerZlatko Buljan <Zlatko.Buljan@imgtec.com>2016-03-31 08:51:24 +0000
commit6221be8e461ef5ce6cba05904260f697ce09eb81 (patch)
tree886a17f868eab556c6f6faf4c73a2e8a730a0748 /llvm/lib/Target/Mips
parent52aadc8eb869ee5327b98fcff0d8d28d1d7c8dc1 (diff)
downloadbcm5719-llvm-6221be8e461ef5ce6cba05904260f697ce09eb81.tar.gz
bcm5719-llvm-6221be8e461ef5ce6cba05904260f697ce09eb81.zip
[mips][microMIPS] Implement MFC*, MFHC* and DMFC* instructions
Differential Revision: http://reviews.llvm.org/D17334 llvm-svn: 265002
Diffstat (limited to 'llvm/lib/Target/Mips')
-rw-r--r--llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp7
-rw-r--r--llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td66
-rw-r--r--llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td17
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrFPU.td4
-rw-r--r--llvm/lib/Target/Mips/Mips64InstrInfo.td3
-rw-r--r--llvm/lib/Target/Mips/MipsInstrFPU.td16
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.td3
7 files changed, 101 insertions, 15 deletions
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index 8f7aeb286d2..81c18683c4a 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -44,6 +44,7 @@ public:
bool hasMips32r6() const {
return STI.getFeatureBits()[Mips::FeatureMips32r6];
}
+ bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
@@ -919,9 +920,9 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
return Result;
}
- if (hasMips32r6()) {
- DEBUG(dbgs() << "Trying MicroMips32r6FPU table (32-bit opcodes):\n");
- Result = decodeInstruction(DecoderTableMicroMips32r6FPU32, Instr, Insn,
+ if (hasMips32r6() && isFP64()) {
+ DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
+ Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index 1c306048903..b76783a5006 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -65,6 +65,12 @@ class JRCADDIUSP_MMR6_ENC : POOL16C_JRCADDIUSP_FM_MM16R6<0x13>;
class LSA_MMR6_ENC : POOL32A_LSA_FM<0b001111>;
class LWPC_MMR6_ENC : PCREL19_FM_MMR6<0b01>;
class LWM16_MMR6_ENC : POOL16C_LWM_SWM_FM_MM16R6<0x2>;
+class MFC0_MMR6_ENC : POOL32A_MFTC0_FM_MMR6<"mfc0", 0b00011, 0b111100>;
+class MFC1_MMR6_ENC : POOL32F_MFTC1_FM_MMR6<"mfc1", 0b10000000>;
+class MFC2_MMR6_ENC : POOL32A_MFTC2_FM_MMR6<"mfc2", 0b0100110100>;
+class MFHC0_MMR6_ENC : POOL32A_MFTC0_FM_MMR6<"mfhc0", 0b00011, 0b110100>;
+class MFHC1_MMR6_ENC : POOL32F_MFTC1_FM_MMR6<"mfhc1", 0b11000000>;
+class MFHC2_MMR6_ENC : POOL32A_MFTC2_FM_MMR6<"mfhc2", 0b1000110100>;
class MOD_MMR6_ENC : ARITH_FM_MMR6<"mod", 0x158>;
class MODU_MMR6_ENC : ARITH_FM_MMR6<"modu", 0x1d8>;
class MUL_MMR6_ENC : ARITH_FM_MMR6<"mul", 0x18>;
@@ -617,6 +623,47 @@ class MTHC1_D64_MMR6_DESC : MTC1_64_MMR6_DESC_BASE<"mthc1", FGR64Opnd, GPR32Opnd
HARDFLOAT, FGR_64;
class MTHC2_MMR6_DESC : MTC2_MMR6_DESC_BASE<"mthc2", COP2Opnd, GPR32Opnd>;
+class MFC0_MMR6_DESC_BASE<string opstr, RegisterOperand DstRC,
+ RegisterOperand SrcRC> {
+ dag InOperandList = (ins SrcRC:$rs, uimm3:$sel);
+ dag OutOperandList = (outs DstRC:$rt);
+ string AsmString = !strconcat(opstr, "\t$rt, $rs, $sel");
+ list<dag> Pattern = [];
+ Format f = FrmFR;
+ string BaseOpcode = opstr;
+}
+class MFC1_MMR6_DESC_BASE<string opstr, RegisterOperand DstRC,
+ RegisterOperand SrcRC,
+ InstrItinClass Itin = NoItinerary,
+ SDPatternOperator OpNode = null_frag> : MipsR6Inst {
+ dag InOperandList = (ins SrcRC:$fs);
+ dag OutOperandList = (outs DstRC:$rt);
+ string AsmString = !strconcat(opstr, "\t$rt, $fs");
+ list<dag> Pattern = [(set DstRC:$rt, (OpNode SrcRC:$fs))];
+ Format f = FrmFR;
+ InstrItinClass Itinerary = Itin;
+ string BaseOpcode = opstr;
+}
+class MFC2_MMR6_DESC_BASE<string opstr, RegisterOperand DstRC,
+ RegisterOperand SrcRC> {
+ dag InOperandList = (ins SrcRC:$impl);
+ dag OutOperandList = (outs DstRC:$rt);
+ string AsmString = !strconcat(opstr, "\t$rt, $impl");
+ list<dag> Pattern = [];
+ Format f = FrmFR;
+ string BaseOpcode = opstr;
+}
+class MFC0_MMR6_DESC : MFC0_MMR6_DESC_BASE<"mfc0", GPR32Opnd, COP0Opnd>;
+class MFC1_MMR6_DESC : MFC1_MMR6_DESC_BASE<"mfc1", GPR32Opnd, FGR32Opnd,
+ II_MFC1, bitconvert>, HARDFLOAT;
+class MFC2_MMR6_DESC : MFC2_MMR6_DESC_BASE<"mfc2", GPR32Opnd, COP2Opnd>;
+class MFHC0_MMR6_DESC : MFC0_MMR6_DESC_BASE<"mfhc0", GPR32Opnd, COP0Opnd>;
+class MFHC1_D32_MMR6_DESC : MFC1_MMR6_DESC_BASE<"mfhc1", GPR32Opnd, AFGR64Opnd,
+ II_MFHC1>, HARDFLOAT, FGR_32;
+class MFHC1_D64_MMR6_DESC : MFC1_MMR6_DESC_BASE<"mfhc1", GPR32Opnd, FGR64Opnd,
+ II_MFHC1>, HARDFLOAT, FGR_64;
+class MFHC2_MMR6_DESC : MFC2_MMR6_DESC_BASE<"mfhc2", GPR32Opnd, COP2Opnd>;
+
/// Floating Point Instructions
class FARITH_MMR6_DESC_BASE<string instr_asm, RegisterOperand RC,
InstrItinClass Itin, bit isComm,
@@ -1083,11 +1130,22 @@ def MTC1_MMR6 : StdMMR6Rel, MTC1_MMR6_DESC, MTC1_MMR6_ENC, ISA_MICROMIPS32R6;
def MTC2_MMR6 : StdMMR6Rel, MTC2_MMR6_ENC, MTC2_MMR6_DESC, ISA_MICROMIPS32R6;
def MTHC0_MMR6 : R6MMR6Rel, MTHC0_MMR6_ENC, MTHC0_MMR6_DESC, ISA_MICROMIPS32R6;
def MTHC1_D32_MMR6 : StdMMR6Rel, MTHC1_D32_MMR6_DESC, MTHC1_MMR6_ENC, ISA_MICROMIPS32R6;
-let DecoderNamespace = "MicroMips32r6FPU" in {
+let DecoderNamespace = "MicroMips32r6FP64" in {
def MTHC1_D64_MMR6 : R6MMR6Rel, MTHC1_D64_MMR6_DESC, MTHC1_MMR6_ENC,
ISA_MICROMIPS32R6;
}
def MTHC2_MMR6 : StdMMR6Rel, MTHC2_MMR6_ENC, MTHC2_MMR6_DESC, ISA_MICROMIPS32R6;
+def MFC0_MMR6 : StdMMR6Rel, MFC0_MMR6_ENC, MFC0_MMR6_DESC, ISA_MICROMIPS32R6;
+def MFC1_MMR6 : StdMMR6Rel, MFC1_MMR6_DESC, MFC1_MMR6_ENC, ISA_MICROMIPS32R6;
+def MFC2_MMR6 : StdMMR6Rel, MFC2_MMR6_ENC, MFC2_MMR6_DESC, ISA_MICROMIPS32R6;
+def MFHC0_MMR6 : R6MMR6Rel, MFHC0_MMR6_ENC, MFHC0_MMR6_DESC, ISA_MICROMIPS32R6;
+def MFHC1_D32_MMR6 : StdMMR6Rel, MFHC1_D32_MMR6_DESC, MFHC1_MMR6_ENC,
+ ISA_MICROMIPS32R6;
+let DecoderNamespace = "MicroMips32r6FP64" in {
+ def MFHC1_D64_MMR6 : StdMMR6Rel, MFHC1_D64_MMR6_DESC, MFHC1_MMR6_ENC,
+ ISA_MICROMIPS32R6;
+}
+def MFHC2_MMR6 : StdMMR6Rel, MFHC2_MMR6_ENC, MFHC2_MMR6_DESC, ISA_MICROMIPS32R6;
def MOD_MMR6 : R6MMR6Rel, MOD_MMR6_DESC, MOD_MMR6_ENC, ISA_MICROMIPS32R6;
def MODU_MMR6 : R6MMR6Rel, MODU_MMR6_DESC, MODU_MMR6_ENC, ISA_MICROMIPS32R6;
def MUL_MMR6 : R6MMR6Rel, MUL_MMR6_DESC, MUL_MMR6_ENC, ISA_MICROMIPS32R6;
@@ -1333,6 +1391,12 @@ def : MipsInstAlias<"mtc0 $rt, $rs",
def : MipsInstAlias<"mthc0 $rt, $rs",
(MTHC0_MMR6 COP0Opnd:$rs, GPR32Opnd:$rt, 0), 0>,
ISA_MICROMIPS32R6;
+def : MipsInstAlias<"mfc0 $rt, $rs",
+ (MFC0_MMR6 GPR32Opnd:$rt, COP0Opnd:$rs, 0), 0>,
+ ISA_MICROMIPS32R6;
+def : MipsInstAlias<"mfhc0 $rt, $rs",
+ (MFHC0_MMR6 GPR32Opnd:$rt, COP0Opnd:$rs, 0), 0>,
+ ISA_MICROMIPS32R6;
//===----------------------------------------------------------------------===//
//
diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
index 74e228728b4..0cc99ac4cb6 100644
--- a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td
@@ -34,6 +34,9 @@ class DINS_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b001100>;
class DMTC0_MM64R6_ENC : POOL32S_DMFTC0_FM_MMR6<"dmtc0", 0b01011>;
class DMTC1_MM64R6_ENC : POOL32F_MFTC1_FM_MMR6<"dmtc1", 0b10110000>;
class DMTC2_MM64R6_ENC : POOL32A_MFTC2_FM_MMR6<"dmtc2", 0b0111110100>;
+class DMFC0_MM64R6_ENC : POOL32S_DMFTC0_FM_MMR6<"dmfc0", 0b00011>;
+class DMFC1_MM64R6_ENC : POOL32F_MFTC1_FM_MMR6<"dmfc1", 0b10010000>;
+class DMFC2_MM64R6_ENC : POOL32A_MFTC2_FM_MMR6<"dmfc2", 0b0110110100>;
//===----------------------------------------------------------------------===//
//
@@ -106,6 +109,11 @@ class DMTC1_MM64R6_DESC : MTC1_MMR6_DESC_BASE<"dmtc1", FGR64Opnd, GPR64Opnd,
II_DMTC1, bitconvert>;
class DMTC2_MM64R6_DESC : MTC2_MMR6_DESC_BASE<"dmtc2", COP2Opnd, GPR64Opnd>;
+class DMFC0_MM64R6_DESC : MFC0_MMR6_DESC_BASE<"dmfc0", GPR64Opnd, COP0Opnd>;
+class DMFC1_MM64R6_DESC : MFC1_MMR6_DESC_BASE<"dmfc1", GPR64Opnd, FGR64Opnd,
+ II_DMFC1, bitconvert>;
+class DMFC2_MM64R6_DESC : MFC2_MMR6_DESC_BASE<"dmfc2", GPR64Opnd, COP2Opnd>;
+
//===----------------------------------------------------------------------===//
//
// Instruction Definitions
@@ -144,6 +152,12 @@ let DecoderNamespace = "MicroMipsR6" in {
ISA_MICROMIPS64R6;
def DMTC2_MM64R6 : StdMMR6Rel, DMTC2_MM64R6_ENC, DMTC2_MM64R6_DESC,
ISA_MICROMIPS64R6;
+ def DMFC0_MM64R6 : StdMMR6Rel, DMFC0_MM64R6_ENC, DMFC0_MM64R6_DESC,
+ ISA_MICROMIPS64R6;
+ def DMFC1_MM64R6 : StdMMR6Rel, DMFC1_MM64R6_DESC, DMFC1_MM64R6_ENC,
+ ISA_MICROMIPS64R6;
+ def DMFC2_MM64R6 : StdMMR6Rel, DMFC2_MM64R6_ENC, DMFC2_MM64R6_DESC,
+ ISA_MICROMIPS64R6;
}
//===----------------------------------------------------------------------===//
@@ -151,3 +165,6 @@ let DecoderNamespace = "MicroMipsR6" in {
//===----------------------------------------------------------------------===//
def : MipsInstAlias<"dmtc0 $rt, $rd",
(DMTC0_MM64R6 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
+def : MipsInstAlias<"dmfc0 $rt, $rd",
+ (DMFC0_MM64R6 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>,
+ ISA_MICROMIPS64R6;
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
index a768ef201f8..3208f2b9f89 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
@@ -114,8 +114,6 @@ def MFC1_MM : MMRel, MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd,
II_MFC1, bitconvert>, MFC1_FM_MM<0x80>;
def MTC1_MM : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd,
II_MTC1, bitconvert>, MFC1_FM_MM<0xa0>;
-def MFHC1_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
- MFC1_FM_MM<0xc0>, ISA_MIPS32R2, FGR_32;
def MADD_S_MM : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S, fadd>,
MADDS_FM_MM<0x1>;
@@ -147,4 +145,6 @@ let AdditionalPredicates = [InMicroMips] in {
fsqrt>, ROUND_W_FM_MM<0, 0x28>;
def MTHC1_MM : MMRel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
MFC1_FM_MM<0xe0>, ISA_MIPS32R2, FGR_32;
+ def MFHC1_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
+ MFC1_FM_MM<0xc0>, ISA_MIPS32R2, FGR_32;
}
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index fc4d76b518a..bc7ddd405a4 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -628,10 +628,11 @@ def : MipsInstAlias<"dsrl $rd, $rt, $rs",
ISA_MIPS3;
// Two operand (implicit 0 selector) versions:
-def : MipsInstAlias<"dmfc0 $rt, $rd", (DMFC0 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>;
let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"dmtc0 $rt, $rd",
(DMTC0 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
+ def : MipsInstAlias<"dmfc0 $rt, $rd",
+ (DMFC0 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>;
}
def : MipsInstAlias<"dmfc2 $rt, $rd", (DMFC2 GPR64Opnd:$rt, COP2Opnd:$rd, 0), 0>;
def : MipsInstAlias<"dmtc2 $rt, $rd", (DMTC2 COP2Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index f9e1679d67b..8e58272dc6e 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -367,11 +367,13 @@ def MFC1 : MMRel, MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd, II_MFC1,
bitconvert>, MFC1_FM<0>;
def MTC1 : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, II_MTC1,
bitconvert>, MFC1_FM<4>;
-def MFHC1_D32 : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
- MFC1_FM<3>, ISA_MIPS32R2, FGR_32;
-def MFHC1_D64 : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>,
- MFC1_FM<3>, ISA_MIPS32R2, FGR_64 {
- let DecoderNamespace = "Mips64";
+let AdditionalPredicates = [NotInMicroMips] in {
+ def MFHC1_D32 : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
+ MFC1_FM<3>, ISA_MIPS32R2, FGR_32;
+ def MFHC1_D64 : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>,
+ MFC1_FM<3>, ISA_MIPS32R2, FGR_64 {
+ let DecoderNamespace = "Mips64";
+ }
}
let AdditionalPredicates = [NotInMicroMips] in {
def MTHC1_D32 : MMRel, StdMMR6Rel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
@@ -381,11 +383,11 @@ let AdditionalPredicates = [NotInMicroMips] in {
let DecoderNamespace = "Mips64";
}
}
-def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, II_DMFC1,
- bitconvert>, MFC1_FM<1>, ISA_MIPS3;
let AdditionalPredicates = [NotInMicroMips] in {
def DMTC1 : MTC1_FT<"dmtc1", FGR64Opnd, GPR64Opnd, II_DMTC1,
bitconvert>, MFC1_FM<5>, ISA_MIPS3;
+ def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, II_DMFC1,
+ bitconvert>, MFC1_FM<1>, ISA_MIPS3;
}
def FMOV_S : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>,
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index f0780add250..0302c430aaf 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -1908,10 +1908,11 @@ def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, uimm5_inssize_plus1, MipsIns>,
EXT_FM<4>;
/// Move Control Registers From/To CPU Registers
-def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
let AdditionalPredicates = [NotInMicroMips] in {
def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>,
ISA_MIPS32;
+ def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>,
+ ISA_MIPS32;
}
def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
OpenPOWER on IntegriCloud