summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@mips.com>2018-02-28 13:02:44 +0000
committerSimon Dardis <simon.dardis@mips.com>2018-02-28 13:02:44 +0000
commit4529aac2de3ffccbf015503681bb5c9712e295b7 (patch)
treef864ec893cc50a6584f0acf6cce09d319cb458d8
parent9ac01b074b15d3af3470dedd6ee19b95070ed50d (diff)
downloadbcm5719-llvm-4529aac2de3ffccbf015503681bb5c9712e295b7.tar.gz
bcm5719-llvm-4529aac2de3ffccbf015503681bb5c9712e295b7.zip
[mips] Begin reworking instruction predicates for ISAs/encodings (1/N)
The MIPS backend has inconsistent usage of instruction predicates for assembly and code generation. The issue arises from supporting three encodings, two (MIPS and microMIPS) of which have a near 1:1 instruction mapping across ISA revisions and a third encoding with a more restricted set of instructions (MIPS16e). To enforce consistent usage, each of the ISA_* adjectives has (or will have) the relevant encoding attached to it along the relevant ISA revision where the instruction is defined. Each instruction, pattern or alias will then have the correct ISA adjective attached to it, and the base instruction description classes will have any predicates relating to ISA encoding or revision removed. Pseudo instructions will also be guarded for the encoding or ABI that they are supported in. Finally, the hasStandardEncoding() / inMicroMipsMode() / inMips16Mode() methods of MipsSubtarget will be changed such that only one can be true at any one time. The result of this is that code generation and assembly will produce the correct encoding up front, while code generated from pseudo instructions and other inserted sequences of instructions will be able to rely on the mapping tables to produce the correct encoding. This should fix numerous bugs where the result 'happens' to be correct but has edge cases where microMIPS and MIPS have subtle differences (e.g. microMIPSR6 using 'j', 'jal' instructions.) This patch starts the process by changing most of the ISA adjectives to make use of the EncodingPredicate member of PredicateControl. Follow on patches will annotate instructions with their correct ISA adjective and eliminate the usage of "let Predicates = [..]", "let AdditionalPredicates = [..]" and "isCodeGenOnly = 1" in the cases where it was used to control instruction availability. Contributions from Nitesh Jain. Reviewers: atanasyan Differential Revision: https://reviews.llvm.org/D41434 llvm-svn: 326322
-rw-r--r--llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td3
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.td96
-rw-r--r--llvm/lib/Target/Mips/MipsScheduleP5600.td3
3 files changed, 80 insertions, 22 deletions
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td
index 1f4d8d26bbd..af52978c4b8 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td
@@ -20,7 +20,8 @@ class MMR6Arch<string opstr> {
// Class used for microMIPS32r6 instructions.
class MicroMipsR6Inst16 : PredicateControl {
string DecoderNamespace = "MicroMipsR6";
- let InsnPredicates = [HasMicroMips32r6];
+ let InsnPredicates = [HasMips32r6];
+ let EncodingPredicates = [InMicroMips];
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 3ecf78e6e09..2e0ddd04a83 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -206,8 +206,6 @@ def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
AssemblerPredicate<"FeatureMips64r6">;
def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
AssemblerPredicate<"!FeatureMips64r6">;
-def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
- AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
AssemblerPredicate<"FeatureMips16">;
def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
@@ -277,88 +275,147 @@ class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
// subtractive predicate will hopefully keep us under the 32 predicate
// limit long enough to develop an alternative way to handle P1||P2
// predicates.
+class ISA_MIPS1 {
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
class ISA_MIPS1_NOT_MIPS3 {
list<Predicate> InsnPredicates = [NotMips3];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
class ISA_MIPS1_NOT_4_32 {
list<Predicate> InsnPredicates = [NotMips4_32];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
class ISA_MIPS1_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS2 {
+ list<Predicate> InsnPredicates = [HasMips2];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
-class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
class ISA_MIPS2_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS3 {
+ list<Predicate> InsnPredicates = [HasMips3];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
-class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
class ISA_MIPS3_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS32 {
+ list<Predicate> InsnPredicates = [HasMips32];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
-class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
class ISA_MIPS32_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS32R2 {
+ list<Predicate> InsnPredicates = [HasMips32r2];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
-class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
class ISA_MIPS32R2_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS32R5 {
+ list<Predicate> InsnPredicates = [HasMips32r5];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS64 {
+ list<Predicate> InsnPredicates = [HasMips64];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
-class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
-class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
class ISA_MIPS64_NOT_64R6 {
list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS64R2 {
+ list<Predicate> InsnPredicates = [HasMips64r2];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS32R6 {
+ list<Predicate> InsnPredicates = [HasMips32r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MIPS64R6 {
+ list<Predicate> InsnPredicates = [HasMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
+class ISA_MICROMIPS {
+ list<Predicate> EncodingPredicates = [InMicroMips];
}
-class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
-class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
-class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
-class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
class ISA_MICROMIPS32R6 {
- list<Predicate> InsnPredicates = [HasMicroMips32r6];
+ list<Predicate> InsnPredicates = [HasMips32r6];
+ list<Predicate> EncodingPredicates = [InMicroMips];
+}
+class ISA_MICROMIPS64R6 {
+ list<Predicate> InsnPredicates = [HasMips64r6];
+ list<Predicate> EncodingPredicates = [InMicroMips];
}
class ISA_MICROMIPS32_NOT_MIPS32R6 {
- list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
+ list<Predicate> InsnPredicates = [NotMips32r6];
+ list<Predicate> EncodingPredicates = [InMicroMips];
}
-
class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
class INSN_EVA_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
}
// The portions of MIPS-III that were also added to MIPS32
-class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
+class INSN_MIPS3_32 {
+ list<Predicate> InsnPredicates = [HasMips3_32];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
// The portions of MIPS-III that were also added to MIPS32 but were removed in
// MIPS32r6 and MIPS64r6.
class INSN_MIPS3_32_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
// The portions of MIPS-III that were also added to MIPS32
-class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
+class INSN_MIPS3_32R2 {
+ list<Predicate> InsnPredicates = [HasMips3_32r2];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
// The portions of MIPS-IV that were also added to MIPS32.
-class INSN_MIPS4_32 { list <Predicate> InsnPredicates = [HasMips4_32]; }
+class INSN_MIPS4_32 {
+ list <Predicate> InsnPredicates = [HasMips4_32];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
+}
// The portions of MIPS-IV that were also added to MIPS32 but were removed in
// MIPS32r6 and MIPS64r6.
class INSN_MIPS4_32_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
// The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
// MIPS32r6 and MIPS64r6.
class INSN_MIPS4_32R2_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
// The portions of MIPS-IV that were also added to MIPS32r2.
class INSN_MIPS4_32R2 {
list<Predicate> InsnPredicates = [HasMips4_32r2];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
// The portions of MIPS-V that were also added to MIPS32r2 but were removed in
// MIPS32r6 and MIPS64r6.
class INSN_MIPS5_32R2_NOT_32R6_64R6 {
list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
+ list<Predicate> EncodingPredicates = [HasStdEnc];
}
class ASE_CNMIPS {
@@ -392,7 +449,8 @@ class ASE_MT {
// Class used for separating microMIPSr6 and microMIPS (r3) instruction.
// It can be used only on instructions that doesn't inherit PredicateControl.
class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
- let InsnPredicates = [InMicroMips, NotMips32r6];
+ let InsnPredicates = [NotMips32r6];
+ let EncodingPredicates = [InMicroMips];
}
class ASE_NOT_DSP {
diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index 440f93d5b7e..556ef9ca295 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -18,8 +18,7 @@ def MipsP5600Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = [HasMips32r6, HasMips64r6,
HasMips64, HasMips64r2, HasCnMips,
InMicroMips, InMips16Mode,
- HasMicroMips32r6, HasDSP,
- HasDSPR2, HasMT];
+ HasDSP, HasDSPR2, HasMT];
}
OpenPOWER on IntegriCloud