From 0173ef77b6bb8d8237b96d14756e29075a6fe29e Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 23 Aug 2022 11:27:30 +0530 Subject: [PATCH 001/123] nMIPS: Refactor ArithLoginR32 to ArithLogicR32 --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 40 +++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index eda4057fca1e9..1156b4b83e448 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -88,7 +88,7 @@ def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N-> //===----------------------------------------------------------------------===// // 32-bit arithmetic and logical instructions with 3 register operands. -class ArithLoginR32: InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), @@ -116,7 +116,7 @@ class ArithLogicI32, InstSize32; class DivMod : - ArithLoginR32 { + ArithLogicR32 { // Need to insert TEQ, because DIV(U)/MOD(U) don't trap on division by zero. bit usesCustomInserter = 1; } @@ -325,24 +325,24 @@ class ReverseNM: //===----------------------------------------------------------------------===// // _POOL32A0_0 pool of instructions. -def SLLV_NM : ArithLoginR32<"sllv", GPR32NMOpnd, shl>; -def SRLV_NM : ArithLoginR32<"srlv", GPR32NMOpnd, srl>; -def SRAV_NM : ArithLoginR32<"srav", GPR32NMOpnd, sra>; -def ROTRV_NM : ArithLoginR32<"rotrv", GPR32NMOpnd, rotr>; -def ADD_NM : ArithLoginR32<"add", GPR32NMOpnd>; -def ADDu_NM : ArithLoginR32<"addu", GPR32NMOpnd, add>; -def SUB_NM : ArithLoginR32<"sub", GPR32NMOpnd>; -def SUBu_NM : ArithLoginR32<"subu", GPR32NMOpnd, sub>; -def AND_NM : ArithLoginR32<"and", GPR32NMOpnd, and>; -def OR_NM : ArithLoginR32<"or", GPR32NMOpnd, or>; -def NOR_NM : ArithLoginR32<"nor", GPR32NMOpnd>; -def XOR_NM : ArithLoginR32<"xor", GPR32NMOpnd, xor>; -def SLT_NM : ArithLoginR32<"slt", GPR32NMOpnd, setlt>; -def SLTU_NM : ArithLoginR32<"sltu", GPR32NMOpnd, setult>; -def MUL_NM : ArithLoginR32<"mul", GPR32NMOpnd, mul>; -def MUH_NM : ArithLoginR32<"muh", GPR32NMOpnd, mulhs>; -def MULU_NM : ArithLoginR32<"mulu", GPR32NMOpnd>; -def MUHU_NM : ArithLoginR32<"muhu", GPR32NMOpnd, mulhu>; +def SLLV_NM : ArithLogicR32<"sllv", GPR32NMOpnd, shl>; +def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, srl>; +def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, sra>; +def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, rotr>; +def ADD_NM : ArithLogicR32<"add", GPR32NMOpnd>; +def ADDu_NM : ArithLogicR32<"addu", GPR32NMOpnd, add>; +def SUB_NM : ArithLogicR32<"sub", GPR32NMOpnd>; +def SUBu_NM : ArithLogicR32<"subu", GPR32NMOpnd, sub>; +def AND_NM : ArithLogicR32<"and", GPR32NMOpnd, and>; +def OR_NM : ArithLogicR32<"or", GPR32NMOpnd, or>; +def NOR_NM : ArithLogicR32<"nor", GPR32NMOpnd>; +def XOR_NM : ArithLogicR32<"xor", GPR32NMOpnd, xor>; +def SLT_NM : ArithLogicR32<"slt", GPR32NMOpnd, setlt>; +def SLTU_NM : ArithLogicR32<"sltu", GPR32NMOpnd, setult>; +def MUL_NM : ArithLogicR32<"mul", GPR32NMOpnd, mul>; +def MUH_NM : ArithLogicR32<"muh", GPR32NMOpnd, mulhs>; +def MULU_NM : ArithLogicR32<"mulu", GPR32NMOpnd>; +def MUHU_NM : ArithLogicR32<"muhu", GPR32NMOpnd, mulhu>; def DIV_NM : DivMod<"div", sdiv>; def MOD_NM : DivMod<"mod", srem>; def DIVU_NM : DivMod<"divu", udiv>; From 297958098ec1042f9b80576a7fc747252d753f39 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 6 Sep 2022 08:49:32 -0700 Subject: [PATCH 002/123] nMIPS: re-organize instruction encodings by pools --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 1 + .../Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 2 +- llvm/lib/Target/Mips/NanoMipsInstrFormats.td | 11 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 272 +++++++++++++++++- 4 files changed, 278 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index b87b674aed3eb..1ad405b193b50 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -8905,6 +8905,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser() { RegisterMCAsmParser Y(getTheMipselTarget()); RegisterMCAsmParser A(getTheMips64Target()); RegisterMCAsmParser B(getTheMips64elTarget()); + RegisterMCAsmParser C(getTheNanoMipsTarget()); } #define GET_REGISTER_MATCHER diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index 97fedee15f0b1..dea78d9732ee0 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -210,6 +210,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() { for (Target *T : {&getTheMipsTarget(), &getTheMips64Target()}) TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEB); - for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget()}) + for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget(), &getTheNanoMipsTarget()}) TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL); } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrFormats.td b/llvm/lib/Target/Mips/NanoMipsInstrFormats.td index 06a4f04f6a345..11f6d44899dfc 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrFormats.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrFormats.td @@ -1,12 +1,11 @@ class InstNM pattern, - InstrItinClass itin = IIPseudo>: + InstrItinClass itin = NoItinerary>: Instruction, PredicateControl, ISA_NANOMIPS { let Namespace = "Mips"; let DecoderNamespace = "NanoMips"; let EncodingPredicates = [HasNanoMips]; string Arch = "nanomips"; - let OutOperandList = outs; let InOperandList = ins; @@ -21,21 +20,25 @@ class InstNM pattern, class InstSize16 { field bits<16> Inst; int Size = 2; + field bits<16> SoftFail = 0; } class InstSize32 { field bits<32> Inst; int Size = 4; + field bits<32> SoftFail = 0; } class InstSize48 { field bits<48> Inst; int Size = 6; + field bits<48> SoftFail = 0; } // nanoMIPS Pseudo Instructions Format -class PseudoInstNM pattern> : - InstNM { +class PseudoInstNM pattern, + InstrItinClass itin = IIPseudo> : + InstNM { let isCodeGenOnly = 1; let isPseudo = 1; } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 1156b4b83e448..a51ec8e844aaa 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -92,7 +92,273 @@ class ArithLogicR32: InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>, InstSize32; + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>, InstSize32 { + +} + +class _Pool_P32 psel> : InstSize32 { + let Inst{31-26} = {psel{4...2}, 0b0, psel{1...0}}; +} + +class _Pool_P_ADDIU psel> : _Pool_P32<0b00000> { + let Inst{25...21} = psel; +} + +class _Pool_P32A psel> : _Pool_P32<0b00100> { + let Inst{2...0} = psel; +} + +class _Pool_P_GP_W psel> : _Pool_P32<0b01000> { + let Inst{1...0} = psel; +} + +class _Pool_P_U12 psel> : _Pool_P32<0b10000> { + let Inst{15-12} = psel; +} + +class _Pool_P_LUI psel> : _Pool_P32<0b11100> { + let Inst{1} = psel; +} + +class _Pool_P_GP_BH psel> : _Pool_P32<0b01001> { + let Inst{20...18} = psel; +} + +class _Pool_P_LS_U12 psel> : _Pool_P32<0b10001> { + let Inst{15...12} = psel; +} + +class _Pool_P_LS_S9 psel> : _Pool_P32<0b10101> { + let Inst{10...8} = psel; +} + +// TODO MOVE.BALC + +class _Pool_P_BAL psel> : _Pool_P32<0b00110> { + let Inst{25} = psel; +} + +class _Pool_P_J psel> : _Pool_P32<0b01010> { + let Inst{15...12} = psel; +} + +class _Pool_P_BR1 psel> : _Pool_P32<0b10010> { + let Inst{15...14} = psel; +} + +class _Pool_P_BR2 psel> : _Pool_P32<0b10110> { + let Inst{15...14} = psel; +} + +class _Pool_P_BRI psel> : _Pool_P32<0b11010> { + let Inst{20...18} = psel; +} + +class _Pool_P_BALRSC psel> : _Pool_P_J<0b1000> { + let Inst{25...21} = psel; +} + +// TODO BRSC : _Pool_P_BALRSC<0b00000> +// TODO BALRSC : _Pool_P_BALRSC + +class _Pool_P_SHIFT psel> : _Pool_P_U12<0b1100> { + let Inst{8...5} = psel; +} + +class _Pool_P_ROTX psel> : _Pool_P_U12<0b1101> { + let Inst{11} = psel{1}; + let Inst{5} = psel{0}; +} + +class _Pool_P_INS psel> : _Pool_P_U12<0b1110> { + let Inst{11} = psel{1}; + let Inst{5} = psel{0}; +} + +class _Pool_P_EXT psel> : _Pool_P_U12<0b1111> { + let Inst{11} = psel{1}; + let Inst{5} = psel{0}; +} + +class _Pool_P_PREF_U12 psel> : _Pool_P_LS_U12<0b0011> { + let Inst{25...21} = psel; +} + +class _Pool_P_LS_S0 psel>: _Pool_P_LS_S9<0b000> { + let Inst{14...11} = psel; +} + +class _Pool_P_PREF_S9 psel>: _Pool_P_LS_S0<0b0011> { + let Inst{25...21} = psel; +} + +class _Pool_P_LS_S1 psel>: _Pool_P_LS_S9<0b001> { + let Inst{14...11} = psel; +} + +class _Pool_P_LL psel>: _Pool_P_LS_S1<0b1010> { + let Inst{1...0} = psel; +} + +class _Pool_P_SC psel>: _Pool_P_LS_S1<0b1011> { + let Inst{1...0} = psel; +} + +class _Pool_P_LS_E0 psel>: _Pool_P_LS_S9<0b010> { + let Inst{14...11} = psel; +} + +class _Pool_P_LLE psel>: _Pool_P_LS_E0<0b1010> { + let Inst{1...0} = psel; +} + +class _Pool_P_PREFE psel>: _Pool_P_LS_E0<0b0011> { + let Inst{25...21} = psel; +} + +class _Pool_P_SCE psel>: _Pool_P_LS_E0<0b1011> { + let Inst{1...0} = psel; +} + +class _Pool_P_LS_WM psel>: _Pool_P_LS_S9<0b100> { + let Inst{11} = psel; +} + +class _Pool_P_LS_UAWM psel>: _Pool_P_LS_S9<0b101> { + let Inst{11} = psel; +} + +class _Pool_P16 psel> : InstSize16 { + let Inst{15-10} = {psel{4...2}, 0b1, psel{1...0}}; +} + +class _Pool_P16_MV psel> : _Pool_P16<0b00000> { + let Inst{9...5} = psel; +} + +// TODO LW16 psel> : _Pool_P16<0b00001> + +// TODO BC16 : _Pool_P16<0b00010> + +class _Pool_P16_SR psel> : _Pool_P16<0b00011> { + let Inst{8} = psel; +} + +class _Pool_P16_SHIFT psel> : _Pool_P16<0b00100> { + let Inst{3} = psel; +} + +// TODO LW_SP : _Pool_P16<0b00101> + +// TODO BALC16 : _Pool_P16<0b00110> + +class _Pool_P16_4X4 psel> : _Pool_P16<0b00111> { + let Inst{8} = psel{1}; + let Inst{3} = psel{0}; +} + +class _Pool_P16C psel> : _Pool_P16<0b01000> { + let Inst{0} = psel; +} + +// TODO LW_GP16 : _Pool_P16<0b01001> + +class _Pool_P16_LB psel> : _Pool_P16<0b01011> { + let Inst{3...2} = psel; +} + +class _Pool_P16_A1 psel> : _Pool_P16<0b01100> { + let Inst{6} = psel; +} + +// TODO LW_4X4 : _Pool_P16<0b01101> { + +class _Pool_P16_LH psel> : _Pool_P16<0b01111> { + let Inst{3} = psel{1}; + let Inst{0} = psel{0}; +} + +class _Pool_P16_A2 psel> : _Pool_P16<0b10000> { + let Inst{3} = psel; +} + +//TODO SW_16 : _Pool_P16<0b10001> + +//TODO BEQZC_16 : _Pool_P16<0b10010> + + +class _Pool_P16_ADDU psel> : _Pool_P16<0b10100> { + let Inst{0} = psel; +} + +//TODO SW_SP : _Pool_P16<0b10101> + +// TODO BNEZC_16 : _Pool_P16<0b10110> + +// TODO MOVEP : _Pool_P16<0b10111> + +// TODO LI16 : _Pool_P16<0b11000> + +// TODO SW_GP16 : _Pool_P16<0b10001> + +class _Pool_P16_BR psel> : _Pool_P16<0b11010> { + let Inst{3...0} = psel; +} + +class _Pool_P16_RI psel> : _Pool_P16_MV<0b00000> { + let Inst{4...3} = psel; +} + +class _Pool_P16_SYSCALL psel> : _Pool_P16_RI<0b01> { + let Inst{2} = psel; +} + +// TODO MOVE_16 : _Pool_P16_RI + +// TODO ANDI_16 : _Pool_P16<0b11100> + +// TODO SW_4X4 : _Pool_P16<0b11101> + +// TODO MOVEP_REV : _Pool_P16<0b11111> + + + +class _Pool_P_RI psel> : _Pool_P_ADDIU<0b00000> { + let Inst{20...19} = psel; +} + +class _Pool_POOL32A0 psel> : _Pool_P32A<0b000> { + let Inst{5} = psel; +} + +class _Pool_POOL32A0_0 psel> : _Pool_POOL32A0<0b0> { + let Inst{9...6} = psel{5...2}; + let Inst{4...3} = psel{1...0}; +} + +class _Pool_POOL32A0_0a : _Pool_POOL32A0_0<0b000010>; + + +class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { + let Inst{5...3} = psel; +} + +// TODO BC_32 : _Pool_P_BAL<0b0> + + + +class ArithLogicR32a: + InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), + !strconcat(opstr, "\t$rd, $rs, $rt"), + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]> { +// bits<5> rd; +// bits<5> rs; +// bits<5> rt; +// let Inst{25...21} = rt; +// let Inst{20...16} = rs; +// let Inst{15...11} = rd; +} // 16-bit arithmetic and logical instructions with 2 register operands. class ArithLogicR16: InstNM<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), - [(operator RO:$rs)]>, InstSize16 { + [(operator RO:$rs)]>, _Pool_P16_BR<0b0000> { let isTerminator = 1; let isBarrier = 1; let isCTI = 1; @@ -325,7 +591,7 @@ class ReverseNM: //===----------------------------------------------------------------------===// // _POOL32A0_0 pool of instructions. -def SLLV_NM : ArithLogicR32<"sllv", GPR32NMOpnd, shl>; +def SLLV_NM : ArithLogicR32a<"sllv", GPR32NMOpnd, shl>, _Pool_POOL32A0_0a; def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, srl>; def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, sra>; def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, rotr>; From bb6774ba6cc411ba204bede428050f7408d321fb Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Thu, 15 Sep 2022 14:06:46 -0700 Subject: [PATCH 003/123] Fix FeatureRelax for nanoMIPS subtarget --- llvm/lib/Target/Mips/Mips.td | 8 +++++++- llvm/lib/Target/Mips/MipsSubtarget.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index 3cae4ea1974dd..c816d112ade14 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -148,9 +148,15 @@ def FeatureMips64r6 : SubtargetFeature<"mips64r6", "MipsArchVersion", "Mips64r6 ISA Support [experimental]", [FeatureMips32r6, FeatureMips64r5, FeatureNaN2008, FeatureAbs2008]>; + +def FeatureRelax : SubtargetFeature<"relax", "UseLinkerRelax", + "true", + "Enable linker relaxation">; + def FeatureNanoMips : SubtargetFeature<"nanomips", "MipsArchVersion", "NanoMips", - "NanoMips ISA Support [experimental]">; + "NanoMips ISA Support [experimental]", + [FeatureRelax]>; def FeatureNMS1 : SubtargetFeature<"nms1", "MipsArchVersion", "NanoMips", "NanoMips ISA Support [experimental]">; diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 7fcc7d5b46c72..0d6650deaf76d 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -202,6 +202,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo { // Use unaliged loads and stores (nanoMIPS only). bool UseUnalignedLoadStore = false; + // Use linker relaxations + bool UseLinkerRelax = true; + /// The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. Align stackAlignment; From f44277a8f8b784fc6f6f01c977eb280c2868710b Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 17 Sep 2022 03:59:32 -0700 Subject: [PATCH 004/123] Add encodings for register-register arithmetic & logic instructions --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 74 ++++++++++------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index a51ec8e844aaa..719d4ea741c1d 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -87,14 +87,6 @@ def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N-> // //===----------------------------------------------------------------------===// -// 32-bit arithmetic and logical instructions with 3 register operands. -class ArithLogicR32: - InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), - !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>, InstSize32 { - -} class _Pool_P32 psel> : InstSize32 { let Inst{31-26} = {psel{4...2}, 0b0, psel{1...0}}; @@ -334,31 +326,27 @@ class _Pool_POOL32A0 psel> : _Pool_P32A<0b000> { class _Pool_POOL32A0_0 psel> : _Pool_POOL32A0<0b0> { let Inst{9...6} = psel{5...2}; let Inst{4...3} = psel{1...0}; + bits<5> rd; + bits<5> rs; + bits<5> rt; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...11} = rd; } -class _Pool_POOL32A0_0a : _Pool_POOL32A0_0<0b000010>; - - class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { let Inst{5...3} = psel; } // TODO BC_32 : _Pool_P_BAL<0b0> +// 32-bit arithmetic and logical instructions with 3 register operands. - -class ArithLogicR32a: InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]> { -// bits<5> rd; -// bits<5> rs; -// bits<5> rt; -// let Inst{25...21} = rt; -// let Inst{20...16} = rs; -// let Inst{15...11} = rd; -} + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>; // 16-bit arithmetic and logical instructions with 2 register operands. class ArithLogicR16: //===----------------------------------------------------------------------===// // _POOL32A0_0 pool of instructions. -def SLLV_NM : ArithLogicR32a<"sllv", GPR32NMOpnd, shl>, _Pool_POOL32A0_0a; -def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, srl>; -def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, sra>; -def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, rotr>; -def ADD_NM : ArithLogicR32<"add", GPR32NMOpnd>; -def ADDu_NM : ArithLogicR32<"addu", GPR32NMOpnd, add>; -def SUB_NM : ArithLogicR32<"sub", GPR32NMOpnd>; -def SUBu_NM : ArithLogicR32<"subu", GPR32NMOpnd, sub>; -def AND_NM : ArithLogicR32<"and", GPR32NMOpnd, and>; -def OR_NM : ArithLogicR32<"or", GPR32NMOpnd, or>; -def NOR_NM : ArithLogicR32<"nor", GPR32NMOpnd>; -def XOR_NM : ArithLogicR32<"xor", GPR32NMOpnd, xor>; -def SLT_NM : ArithLogicR32<"slt", GPR32NMOpnd, setlt>; -def SLTU_NM : ArithLogicR32<"sltu", GPR32NMOpnd, setult>; -def MUL_NM : ArithLogicR32<"mul", GPR32NMOpnd, mul>; -def MUH_NM : ArithLogicR32<"muh", GPR32NMOpnd, mulhs>; -def MULU_NM : ArithLogicR32<"mulu", GPR32NMOpnd>; -def MUHU_NM : ArithLogicR32<"muhu", GPR32NMOpnd, mulhu>; -def DIV_NM : DivMod<"div", sdiv>; -def MOD_NM : DivMod<"mod", srem>; -def DIVU_NM : DivMod<"divu", udiv>; -def MODU_NM : DivMod<"modu", urem>; +def SLLV_NM : ArithLogicR32<"sllv", GPR32NMOpnd, shl>, _Pool_POOL32A0_0<0b000010>; +def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, srl>, _Pool_POOL32A0_0<0b000110>; +def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, sra>, _Pool_POOL32A0_0<0b001010>; +def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, rotr>, _Pool_POOL32A0_0<0b001110>; +def ADD_NM : ArithLogicR32<"add", GPR32NMOpnd>, _Pool_POOL32A0_0<0b010010>; +def ADDu_NM : ArithLogicR32<"addu", GPR32NMOpnd, add>, _Pool_POOL32A0_0<0b010110>; +def SUB_NM : ArithLogicR32<"sub", GPR32NMOpnd>, _Pool_POOL32A0_0<0b011010>; +def SUBu_NM : ArithLogicR32<"subu", GPR32NMOpnd, sub>, _Pool_POOL32A0_0<0b011110>; +def AND_NM : ArithLogicR32<"and", GPR32NMOpnd, and>, _Pool_POOL32A0_0<0b100110>; +def OR_NM : ArithLogicR32<"or", GPR32NMOpnd, or>, _Pool_POOL32A0_0<0b101010>; +def NOR_NM : ArithLogicR32<"nor", GPR32NMOpnd>, _Pool_POOL32A0_0<0b101110>; +def XOR_NM : ArithLogicR32<"xor", GPR32NMOpnd, xor>, _Pool_POOL32A0_0<0b110010>; +def SLT_NM : ArithLogicR32<"slt", GPR32NMOpnd, setlt>, _Pool_POOL32A0_0<0b110110>; +def SLTU_NM : ArithLogicR32<"sltu", GPR32NMOpnd, setult>, _Pool_POOL32A0_0<0b111010>; +def MUL_NM : ArithLogicR32<"mul", GPR32NMOpnd, mul>, _Pool_POOL32A0_0<0b000011>; +def MUH_NM : ArithLogicR32<"muh", GPR32NMOpnd, mulhs>, _Pool_POOL32A0_0<0b000111>; +def MULU_NM : ArithLogicR32<"mulu", GPR32NMOpnd>, _Pool_POOL32A0_0<0b001011>; +def MUHU_NM : ArithLogicR32<"muhu", GPR32NMOpnd, mulhu>, _Pool_POOL32A0_0<0b001111>; +def DIV_NM : DivMod<"div", sdiv>, _Pool_POOL32A0_0<0b010011>; +def MOD_NM : DivMod<"mod", srem>, _Pool_POOL32A0_0<0b010111>; +def DIVU_NM : DivMod<"divu", udiv>, _Pool_POOL32A0_0<0b011011>; +def MODU_NM : DivMod<"modu", urem>, _Pool_POOL32A0_0<0b011111>; // P.U12 pool of instructions def ORI_NM : ArithLogicI32<"ori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, or>; From a4380387b15f07ed8b03dfcc6eaa5c2f035a1b69 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 17 Sep 2022 04:04:35 -0700 Subject: [PATCH 005/123] Inhibit expansion of DIVU as a macro with zero-check for nanoMIPS --- llvm/lib/Target/Mips/MipsInstrInfo.td | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 0cfddd41194a7..6485f4866e28a 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -306,6 +306,10 @@ class ISA_MIPS1_NOT_32R6_64R6 { list InsnPredicates = [NotMips32r6, NotMips64r6]; list EncodingPredicates = [HasStdEnc]; } +class ISA_MIPS1_NOT_32R6_64R6_NMIPS { + list InsnPredicates = [NotMips32r6, NotMips64r6, NotNanoMips]; + list EncodingPredicates = [HasStdEnc]; +} class ISA_MIPS2 { list InsnPredicates = [HasMips2]; list EncodingPredicates = [HasStdEnc]; @@ -3022,7 +3026,7 @@ def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), "divu\t$rd, $rs, $rt">, - ISA_MIPS1_NOT_32R6_64R6; + ISA_MIPS1_NOT_32R6_64R6_NMIPS; def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs, simm32:$imm), "divu\t$rd, $rs, $imm">, From 699e41b446c7c03a710b2199d02b0a1495377883 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 17 Sep 2022 04:20:33 -0700 Subject: [PATCH 006/123] Add encodings for arith/logic instructions with immediate operand Includes P.SHIFT, P.U12, P.INS, P.EXT --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 160 ++++++++++++++-------- 1 file changed, 102 insertions(+), 58 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 719d4ea741c1d..405f406088b82 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -155,21 +155,27 @@ class _Pool_P_BALRSC psel> : _Pool_P_J<0b1000> { class _Pool_P_SHIFT psel> : _Pool_P_U12<0b1100> { let Inst{8...5} = psel; + bits<5> shift; + bits<5> rs; + bits<5> rt; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{4...0} = shift; } -class _Pool_P_ROTX psel> : _Pool_P_U12<0b1101> { - let Inst{11} = psel{1}; - let Inst{5} = psel{0}; +class _Pool_P_SLL rt, bits<5> shift> : _Pool_P_SHIFT<0b0000> { + let Inst{25...21} = rt; + let Inst{4...0} = shift; } -class _Pool_P_INS psel> : _Pool_P_U12<0b1110> { +class _Pool_P_ROTX psel> : _Pool_P_U12<0b1101> { let Inst{11} = psel{1}; let Inst{5} = psel{0}; } -class _Pool_P_EXT psel> : _Pool_P_U12<0b1111> { - let Inst{11} = psel{1}; - let Inst{5} = psel{0}; +class _Pool_P_EXT_INS psel> : _Pool_P_U12 { + let Inst{11} = 0; + let Inst{5} = 0; } class _Pool_P_PREF_U12 psel> : _Pool_P_LS_U12<0b0011> { @@ -324,14 +330,8 @@ class _Pool_POOL32A0 psel> : _Pool_P32A<0b000> { } class _Pool_POOL32A0_0 psel> : _Pool_POOL32A0<0b0> { - let Inst{9...6} = psel{5...2}; - let Inst{4...3} = psel{1...0}; - bits<5> rd; - bits<5> rs; - bits<5> rt; - let Inst{25...21} = rt; - let Inst{20...16} = rs; - let Inst{15...11} = rd; + let Inst{9...6} = psel{5...2}; + let Inst{4...3} = psel{1...0}; } class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { @@ -343,10 +343,18 @@ class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { // 32-bit arithmetic and logical instructions with 3 register operands. class ArithLogicR32 psel, SDPatternOperator OpNode = null_frag>: InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>; + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>, _Pool_POOL32A0_0 { + bits<5> rd; + bits<5> rs; + bits<5> rt; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...11} = rd; +} // 16-bit arithmetic and logical instructions with 2 register operands. class ArithLogicR16 : - ArithLogicINM, InstSize32; + ArithLogicINM; + +class AddiU32 : + ArithLogicINM, _Pool_P32<0b00000> { + bits<5> rt; + bits<5> rs; + bits<12> imm12; + bits<16> imm16; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{11...0} = imm12; +} -class DivMod : - ArithLogicR32 { +class DivMod psel, SDPatternOperator OpNode = null_frag> : + ArithLogicR32 { // Need to insert TEQ, because DIV(U)/MOD(U) don't trap on division by zero. bit usesCustomInserter = 1; } +class CondLogicI32 psel, + SDPatternOperator OpNode = null_frag> : + ArithLogicINM, _Pool_P_U12 { + bits<5> rt; + bits<5> rs; + bits<12> u12; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{11...0} = u12; +} + +class ShiftI32 psel, + SDPatternOperator OpNode = null_frag> : + ArithLogicINM, _Pool_P_SHIFT { + bits<5> rt; + bits<5> rs; + bits<5> u5; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{4...0} = u5; +} + class ExtBaseNM : InstNM<(outs RO:$rt), (ins RO:$rs, uimm5:$pos, uimm5_plus1:$size), "ext\t$rt, $rs, $pos, $size", [(set RO:$rt, (MipsExt RO:$rs, immZExt5:$pos, immZExt5Plus1:$size))], - II_EXT>, InstSize32 { - let isCodeGenOnly = 1; -} + II_EXT>, _Pool_P_EXT_INS<0b1111>; class InsBaseNM : InstNM<(outs RO:$rt), @@ -389,9 +434,8 @@ class InsBaseNM : "ins \t$rt, $rs, $pos, $size", [(set RO:$rt, (MipsIns RO:$rs, immZExt5:$pos, immZExt5Plus1:$size, RO:$src))], - II_INS>, InstSize32 { + II_INS>, _Pool_P_EXT_INS<0b1110> { let Constraints = "$src = $rt"; - let isCodeGenOnly = 1; } class Trap : @@ -579,47 +623,47 @@ class ReverseNM: //===----------------------------------------------------------------------===// // _POOL32A0_0 pool of instructions. -def SLLV_NM : ArithLogicR32<"sllv", GPR32NMOpnd, shl>, _Pool_POOL32A0_0<0b000010>; -def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, srl>, _Pool_POOL32A0_0<0b000110>; -def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, sra>, _Pool_POOL32A0_0<0b001010>; -def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, rotr>, _Pool_POOL32A0_0<0b001110>; -def ADD_NM : ArithLogicR32<"add", GPR32NMOpnd>, _Pool_POOL32A0_0<0b010010>; -def ADDu_NM : ArithLogicR32<"addu", GPR32NMOpnd, add>, _Pool_POOL32A0_0<0b010110>; -def SUB_NM : ArithLogicR32<"sub", GPR32NMOpnd>, _Pool_POOL32A0_0<0b011010>; -def SUBu_NM : ArithLogicR32<"subu", GPR32NMOpnd, sub>, _Pool_POOL32A0_0<0b011110>; -def AND_NM : ArithLogicR32<"and", GPR32NMOpnd, and>, _Pool_POOL32A0_0<0b100110>; -def OR_NM : ArithLogicR32<"or", GPR32NMOpnd, or>, _Pool_POOL32A0_0<0b101010>; -def NOR_NM : ArithLogicR32<"nor", GPR32NMOpnd>, _Pool_POOL32A0_0<0b101110>; -def XOR_NM : ArithLogicR32<"xor", GPR32NMOpnd, xor>, _Pool_POOL32A0_0<0b110010>; -def SLT_NM : ArithLogicR32<"slt", GPR32NMOpnd, setlt>, _Pool_POOL32A0_0<0b110110>; -def SLTU_NM : ArithLogicR32<"sltu", GPR32NMOpnd, setult>, _Pool_POOL32A0_0<0b111010>; -def MUL_NM : ArithLogicR32<"mul", GPR32NMOpnd, mul>, _Pool_POOL32A0_0<0b000011>; -def MUH_NM : ArithLogicR32<"muh", GPR32NMOpnd, mulhs>, _Pool_POOL32A0_0<0b000111>; -def MULU_NM : ArithLogicR32<"mulu", GPR32NMOpnd>, _Pool_POOL32A0_0<0b001011>; -def MUHU_NM : ArithLogicR32<"muhu", GPR32NMOpnd, mulhu>, _Pool_POOL32A0_0<0b001111>; -def DIV_NM : DivMod<"div", sdiv>, _Pool_POOL32A0_0<0b010011>; -def MOD_NM : DivMod<"mod", srem>, _Pool_POOL32A0_0<0b010111>; -def DIVU_NM : DivMod<"divu", udiv>, _Pool_POOL32A0_0<0b011011>; -def MODU_NM : DivMod<"modu", urem>, _Pool_POOL32A0_0<0b011111>; +def SLLV_NM : ArithLogicR32<"sllv", GPR32NMOpnd, 0b000010, shl>; +def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, 0b000110, srl>; +def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, 0b001010, sra>; +def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, 0b001110, rotr>; +def ADD_NM : ArithLogicR32<"add", GPR32NMOpnd, 0b010010>; +def ADDu_NM : ArithLogicR32<"addu", GPR32NMOpnd, 0b010110, add>; +def SUB_NM : ArithLogicR32<"sub", GPR32NMOpnd, 0b011010>; +def SUBu_NM : ArithLogicR32<"subu", GPR32NMOpnd, 0b011110, sub>; +def AND_NM : ArithLogicR32<"and", GPR32NMOpnd, 0b100110, and>; +def OR_NM : ArithLogicR32<"or", GPR32NMOpnd, 0b101010, or>; +def NOR_NM : ArithLogicR32<"nor", GPR32NMOpnd, 0b101110>; +def XOR_NM : ArithLogicR32<"xor", GPR32NMOpnd, 0b110010, xor>; +def SLT_NM : ArithLogicR32<"slt", GPR32NMOpnd, 0b110110, setlt>; +def SLTU_NM : ArithLogicR32<"sltu", GPR32NMOpnd, 0b111010, setult>; +def MUL_NM : ArithLogicR32<"mul", GPR32NMOpnd, 0b000011, mul>; +def MUH_NM : ArithLogicR32<"muh", GPR32NMOpnd, 0b000111, mulhs>; +def MULU_NM : ArithLogicR32<"mulu", GPR32NMOpnd, 0b001011>; +def MUHU_NM : ArithLogicR32<"muhu", GPR32NMOpnd, 0b001111, mulhu>; +def DIV_NM : DivMod<"div", 0b010011, sdiv>; +def MOD_NM : DivMod<"mod", 0b010111, srem>; +def DIVU_NM : DivMod<"divu", 0b011011, udiv>; +def MODU_NM : DivMod<"modu", 0b011111, urem>; // P.U12 pool of instructions -def ORI_NM : ArithLogicI32<"ori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, or>; -def XORI_NM : ArithLogicI32<"xori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, xor>; -def ANDI_NM : ArithLogicI32<"andi", uimm16, GPR32NMOpnd, imm32ZExt12ANDI, and>; -def SLTI_NM : ArithLogicI32<"slti", uimm12_nm, GPR32NMOpnd, imm32ZExt12, setlt>; -def SLTIU_NM : ArithLogicI32<"sltiu", uimm12_nm, GPR32NMOpnd, imm32ZExt12, setult>; -def SEQI_NM : ArithLogicI32<"seqi", uimm12_nm, GPR32NMOpnd, imm32ZExt12, seteq>; - +def ORI_NM : CondLogicI32<"ori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0000, or>; +def XORI_NM : CondLogicI32<"xori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0001, xor>; +def ANDI_NM : CondLogicI32<"andi", uimm16, GPR32NMOpnd, imm32ZExt12ANDI, 0b0010, and>; +def SLTI_NM : CondLogicI32<"slti", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0100, setlt>; +def SLTIU_NM : CondLogicI32<"sltiu", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0101, setult>; +def SEQI_NM : CondLogicI32<"seqi", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0110, seteq>; + // P.SHIFT pool of instructions -def SLL_NM : ArithLogicI32<"sll", uimm5_nm, GPR32NMOpnd, imm32ZExt5, shl>; -def SRL_NM : ArithLogicI32<"srl", uimm5_nm, GPR32NMOpnd, imm32ZExt5, srl>; -def SRA_NM : ArithLogicI32<"sra", uimm5_nm, GPR32NMOpnd, imm32ZExt5, sra>; -def ROTR_NM : ArithLogicI32<"rotr", uimm5_nm, GPR32NMOpnd, imm32ZExt5, rotr>; +def SLL_NM : ShiftI32<"sll", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0000, shl>; +def SRL_NM : ShiftI32<"srl", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0010, srl>; +def SRA_NM : ShiftI32<"sra", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0100, sra>; +def ROTR_NM : ShiftI32<"rotr", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0110, rotr>; def EXT_NM : ExtBaseNM; def INS_NM : InsBaseNM; -def ADDiu_NM : ArithLogicI32<"addiu", uimm16_simm12, GPR32NMOpnd, +def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPR32NMOpnd, imm32SExt12OrZExt16, add>; let Constraints = "$rt = $rs" in def ADDIU48_NM : ArithLogicINM<"addiu[48]", simm32_relaxed, GPR32NMOpnd, From 894af018dfa4c3d1aed9dea50663bc765617189a Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 19 Sep 2022 07:04:54 -0700 Subject: [PATCH 007/123] Add interface to decode nanoMIPS general purpose registers for disassembly --- .../Target/Mips/Disassembler/MipsDisassembler.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 6f197e4245613..4392c46a11752 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -109,6 +109,11 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPR32NMRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1455,6 +1460,13 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPR32NMRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); +} + static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, From baa6d1d827158f0dd881b287a28ffb47ea1464bf Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 19 Sep 2022 07:11:25 -0700 Subject: [PATCH 008/123] Add encodings from trap (TEQ/TNE) instructions --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 405f406088b82..f2d5cb602c954 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -334,6 +334,11 @@ class _Pool_POOL32A0_0 psel> : _Pool_POOL32A0<0b0> { let Inst{4...3} = psel{1...0}; } +class _Pool_P_TRAP isel> : _Pool_POOL32A0_0<0b000000> +{ + let Inst{10} = isel; +} + class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { let Inst{5...3} = psel; } @@ -438,11 +443,18 @@ class InsBaseNM : let Constraints = "$src = $rt"; } -class Trap : - InstNM<(outs), (ins GPR32NMOpnd:$rs, GPR32NMOpnd:$rt, uimm5_nm:$imm), - !strconcat(opstr, "\t$rt, $rs, $imm"), []>, InstSize32 { +class Trap isel> : + InstNM<(outs), (ins RO:$rs, RO:$rt, ImmOp:$imm), + !strconcat(opstr, "\t$rt, $rs, $imm"), []>, + _Pool_P_TRAP { let hasSideEffects = 1; let isCTI = 1; + bits<5> rt; + bits<5> rs; + bits<5> code; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...11} = code; } // Instructions with 1 register (dest) and 1 immediate operand. @@ -681,8 +693,8 @@ def BITREVW_NM : ReverseNM<"bitrevw", GPR32NMOpnd, bitreverse>; def BYTEREVW_NM : ReverseNM<"byterevw", GPR32NMOpnd, bswap>; // P.TRAP pool of instructions. -def TEQ_NM : Trap<"teq">; -def TNE_NM : Trap<"tne">; +def TEQ_NM : Trap<"teq", GPR32NMOpnd, uimm5_nm, 0b0>; +def TNE_NM : Trap<"tne", GPR32NMOpnd, uimm5_nm, 0b1>; def NOT_NM : ArithLogicR16<"not", GPR3Opnd, not>; def XOR16_NM : ArithLogicR16<"xor16", GPR3Opnd>; From d800c7078e611c45c441b046e80f85de4323b934 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 20 Sep 2022 04:40:10 -0700 Subject: [PATCH 009/123] Add 16-bit logic instructions, POOL16C_00 --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 27 ++++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index f2d5cb602c954..72a299af9e829 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -259,6 +259,11 @@ class _Pool_P16C psel> : _Pool_P16<0b01000> { let Inst{0} = psel; } +class _Pool_POOL16C_00 psel> : _Pool_P16<0b01000> { + let Inst{3...2} = psel; + let Inst{1...0} = 0b00; +} + // TODO LW_GP16 : _Pool_P16<0b01001> class _Pool_P16_LB psel> : _Pool_P16<0b01011> { @@ -361,11 +366,17 @@ class ArithLogicR32 isel, SDPatternOperator OpNode = null_frag>: InstNM<(outs RO:$rt), (ins RO:$rs), !strconcat(opstr, "\t$rt, $rs"), - [(set RO:$rt, (OpNode RO:$rs))]>, InstSize16; + [(set RO:$rt, (OpNode RO:$rs))]>, _Pool_POOL16C_00 { + bits<3> rs; + bits<3> rt; + let Inst{9...7} = rt; + let Inst{6...4} = rs; +} // Arithmetic and logical instructions with 2 register operands and immediate. class ArithLogicINM isel> : let isCTI = 1; bits<5> rt; bits<5> rs; - bits<5> code; + bits<5> cd; let Inst{25...21} = rt; let Inst{20...16} = rs; - let Inst{15...11} = code; + let Inst{15...11} = cd; } // Instructions with 1 register (dest) and 1 immediate operand. @@ -696,10 +707,10 @@ def BYTEREVW_NM : ReverseNM<"byterevw", GPR32NMOpnd, bswap>; def TEQ_NM : Trap<"teq", GPR32NMOpnd, uimm5_nm, 0b0>; def TNE_NM : Trap<"tne", GPR32NMOpnd, uimm5_nm, 0b1>; -def NOT_NM : ArithLogicR16<"not", GPR3Opnd, not>; -def XOR16_NM : ArithLogicR16<"xor16", GPR3Opnd>; -def AND16_NM : ArithLogicR16<"and16", GPR3Opnd>; -def OR16_NM : ArithLogicR16<"or16", GPR3Opnd>; +def NOT_NM : ArithLogicR16<"not", GPR3Opnd, 0b00, not>; +def XOR16_NM : ArithLogicR16<"xor16", GPR3Opnd, 0b01>; +def AND16_NM : ArithLogicR16<"and16", GPR3Opnd, 0b10>; +def OR16_NM : ArithLogicR16<"or16", GPR3Opnd, 0b11>; def JRC_NM : IndirectBranchNM<"jrc", GPR32NMOpnd>; From 4c0ec7397c252b056e145effaf05b685b4d517ce Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 9 Oct 2022 12:13:06 -0700 Subject: [PATCH 010/123] 48-bit instructions --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 26 +++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 72a299af9e829..9044fae7d8596 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -112,6 +112,11 @@ class _Pool_P_LUI psel> : _Pool_P32<0b11100> { let Inst{1} = psel; } +class _Pool_P48I psel> : InstSize48 { + let Inst{47...42} = 0b011000; + let Inst{36...32} = psel; +} + class _Pool_P_GP_BH psel> : _Pool_P32<0b01001> { let Inst{20...18} = psel; } @@ -475,6 +480,19 @@ class RegImmNM; +class RegImm48 isel, + SDPatternOperator imm_type = null_frag, + SDPatternOperator OpNode = null_frag> : + InstNM<(outs RO:$rt), (ins Od:$imm), !strconcat(opstr, "\t$rt, $imm"), + [(set RO:$rt, (OpNode imm_type:$imm))]>, _Pool_P48I { + bits<5> rt; + bits<32> imm; + let Inst{41...37} = rt; + let Inst{31...16} = imm{15...0}; + let Inst{15...0} = imm{31...16}; +} + class LoadMemoryNM; let Constraints = "$rt = $rs" in def ADDIU48_NM : ArithLogicINM<"addiu[48]", simm32_relaxed, GPR32NMOpnd, - imm32_NM, add>, InstSize48; + imm32_NM, add>, _Pool_P48I<0b00001>; def LSA_NM : LoadScaledAddressNM<"lsa", GPR32NMOpnd>; @@ -718,10 +736,10 @@ def BALC_NM : CallNM<"balc", MipsJmpLink, tglobaladdr>, InstSize32; def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { -def Li_NM : RegImmNM<"li", simm32_relaxed, GPR32NMOpnd>, InstSize48; -def LA_NM : RegImmNM<"la", simm32_relaxed, GPR32NMOpnd>, InstSize48; +def Li_NM : RegImm48<"li", simm32_relaxed, GPR32NMOpnd, 0b00000>; +def LA_NM : RegImm48<"la", simm32_relaxed, GPR32NMOpnd, 0b00011>; -def LAGPB_NM : RegImmNM<"addiu.b", simm32_relaxed, GPR32NMOpnd>, InstSize48 { +def LAGPB_NM : RegImm48<"addiu.b", simm32_relaxed, GPR32NMOpnd, 0b00010> { let AsmString = "addiu.b $rt, $$gp, %gprel( $imm )"; let isReMaterializable = 1; } From c18d8192dc6ef619c52bd5099f5d9709f09f2213 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 9 Oct 2022 16:46:17 -0700 Subject: [PATCH 011/123] Add 16-bit and 4x4 ADDU variants --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 39 +++++++++++++++++++ .../Mips/Disassembler/MipsDisassembler.cpp | 32 +++++++++++++++ llvm/lib/Target/Mips/MipsRegisterInfo.td | 29 +++++++++++--- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 5 ++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 38 ++++++++++++++++++ 5 files changed, 136 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 1ad405b193b50..5016128597c64 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -923,6 +923,15 @@ class MipsOperand : public MCParsedAsmOperand { return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); } + /// Coerce the register to GPR32 and return the real register for the current + /// target. + unsigned getGPRNM16Reg() const { + assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); + unsigned ClassID = Mips::GPR32RegClassID; + return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + + /// Coerce the register to GPR64 and return the real register for the current /// target. unsigned getGPR64Reg() const { @@ -1081,11 +1090,25 @@ class MipsOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(getGPR32Reg())); } + void addGPR32NMAsmRegOperands(MCInst &Inst, unsigned N) const { + addGPR32AsmRegOperands(Inst, N); + } + void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); } + void addGPRNM16AsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createReg(getGPR32Reg())); + } + + void addGPRNM4x4AsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createReg(getGPR32Reg())); + } + void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); @@ -1695,6 +1718,22 @@ class MipsOperand : public MCParsedAsmOperand { return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; } + bool isNM16AsmReg() const { + if (!(isRegIdx() && RegIdx.Kind)) + return false; + return ((RegIdx.Index >= 4 && RegIdx.Index <= 7) + || (RegIdx.Index >= 16 && RegIdx.Index <= 19)); + + } + + bool isNM4x4AsmReg() const { + if (!(isRegIdx() && RegIdx.Kind)) + return false; + return ((RegIdx.Index >= 4 && RegIdx.Index <= 11) + || (RegIdx.Index >= 16 && RegIdx.Index <= 23)); + + } + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const override { return StartLoc; } /// getEndLoc - Get the location of the last token of this operand. diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 4392c46a11752..76507c49ff625 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -109,6 +109,16 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPR3RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeGPR4RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeGPR32NMRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -1460,6 +1470,28 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPR3RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPR3RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeGPR4RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 15) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPR4RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeGPR32NMRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index 45329b2a52eb1..a8ffa719515d4 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -347,6 +347,11 @@ def GPR3 : RegisterClass<"Mips", [i32], 32, (add A0_NM, A1_NM, A2_NM, A3_NM, S0_NM, S1_NM, S2_NM, S3_NM)>; +def GPR4 : + RegisterClass<"Mips", [i32], 32, + (add A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM, + S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM)>; + class GPR32Class regTypes> : RegisterClass<"Mips", regTypes, 32, (add // Reserved @@ -593,14 +598,24 @@ def GPR32AsmOperand : MipsAsmRegOperand { let PredicateMethod = "isGPRAsmReg"; } +def GPRMM16AsmOperand : MipsAsmRegOperand { + let Name = "GPRMM16AsmReg"; + let PredicateMethod = "isMM16AsmReg"; +} + +def GPRNM16AsmOperand : MipsAsmRegOperand { + let Name = "GPRNM16AsmReg"; + let PredicateMethod = "isNM16AsmReg"; +} + def GPR32NMAsmOperand : MipsAsmRegOperand { let Name = "GPR32NMAsmReg"; let PredicateMethod = "isGPRAsmReg"; } -def GPRMM16AsmOperand : MipsAsmRegOperand { - let Name = "GPRMM16AsmReg"; - let PredicateMethod = "isMM16AsmReg"; +def GPRNM4x4AsmOperand : MipsAsmRegOperand { + let Name = "GPRNM4x4AsmReg"; + let PredicateMethod = "isNM4x4AsmReg"; } def GPRMM16AsmOperandZero : MipsAsmRegOperand { @@ -697,11 +712,15 @@ def GPR32Opnd : RegisterOperand { } def GPR32NMOpnd : RegisterOperand { - let ParserMatchClass = GPR32AsmOperand; + let ParserMatchClass = GPR32NMAsmOperand; } def GPR3Opnd : RegisterOperand { - let ParserMatchClass = GPR32AsmOperand; + let ParserMatchClass = GPRNM16AsmOperand; +} + +def GPR4Opnd : RegisterOperand { + let ParserMatchClass = GPRNM4x4AsmOperand; } def GPRMM16Opnd : RegisterOperand { diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 784f0202ba125..6118f23ca931c 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -111,12 +111,13 @@ def : InstRW<[GenericWriteALU], (instrs ADDIUPC_MMR6, ADDIU_MMR6, ADDU16_MMR6, SELEQZ_MMR6, SELNEZ_MMR6, SLL16_MMR6, SLL_MMR6, SRL16_MMR6, SSNOP_MMR6, SUBU16_MMR6, SUBU_MMR6, SUB_MMR6, WSBH_MMR6, XOR16_MMR6, - XORI_MMR6, XOR_MMR6)>; + XORI_MMR6, XOR_MMR6)>; // nanoMIPS // ============= -def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu_NM, ADDiu_NM, ADDIU48_NM, +def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, + ADDiu_NM, ADDIU48_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 9044fae7d8596..391423c4b530a 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -355,6 +355,19 @@ class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { // TODO BC_32 : _Pool_P_BAL<0b0> +// 16-bit arithmetic and logical instructions with 4x4 register operands, P16_4X4 +class Arith4x4 isel, + SDPatternOperator OpNode = null_frag>: + InstNM<(outs RO:$dst), (ins RO:$rs, RO:$rt), + !strconcat(opstr, "\t$dst, $rs, $rt"), + [(set RO:$dst, (OpNode RO:$rs, RO:$rt))]>, _Pool_P16_4X4 { + let Constraints = "$rt = $dst"; + let isCommutable = 1; + Format Form = FrmR; + let AddedComplexity = -1; +} + // 32-bit arithmetic and logical instructions with 3 register operands. class ArithLogicR32 isel, + SDPatternOperator OpNode = null_frag>: + InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>, _Pool_P16_ADDU { + bits<3> rd; + bits<3> rs; + bits<3> rt; + let Inst{15-10} = 0b101100; + let Inst{9...7} = rt; + let Inst{6...4} = rs; + let Inst{3...1} = rd; + let Inst{0} = 0; +} + // Arithmetic and logical instructions with 2 register operands and immediate. class ArithLogicINM: // //===----------------------------------------------------------------------===// +// 16-bit register operations +let FastISelShouldIgnore = 1 in { +def ADDu16_NM : AddSubR16<"addu", GPR3Opnd, 0b0, add>; +//def SUBu16_NM : AddSubR16<"subu", GPR3Opnd, 0b1, sub>; +def ADDu4x4_NM : Arith4x4<"addu", GPR4Opnd, 0b00>; +//def MULu4x4_NM : Arith4x4<"mulu", GPR4Opnd, 0b01, mul>; +} + // _POOL32A0_0 pool of instructions. def SLLV_NM : ArithLogicR32<"sllv", GPR32NMOpnd, 0b000010, shl>; def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, 0b000110, srl>; @@ -670,6 +707,7 @@ def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, 0b001010, sra>; def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, 0b001110, rotr>; def ADD_NM : ArithLogicR32<"add", GPR32NMOpnd, 0b010010>; def ADDu_NM : ArithLogicR32<"addu", GPR32NMOpnd, 0b010110, add>; + def SUB_NM : ArithLogicR32<"sub", GPR32NMOpnd, 0b011010>; def SUBu_NM : ArithLogicR32<"subu", GPR32NMOpnd, 0b011110, sub>; def AND_NM : ArithLogicR32<"and", GPR32NMOpnd, 0b100110, and>; From f9da54bc83ad71e638e3d04381608bf3922eee66 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 9 Oct 2022 16:51:18 -0700 Subject: [PATCH 012/123] Add ADDIU with positive and negative immediate operands --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 9 +++++ llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 37 +++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 5016128597c64..34454f0b1a614 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1330,6 +1330,10 @@ class MipsOperand : public MCParsedAsmOperand { return isConstantImm() ? isInt(getConstantImm()) : isImm(); } + template bool isNegImm() const { + return (isConstantImm() ? isInt(getConstantImm()) : isImm()) && getConstantImm() < 0; + } + template bool isUImm() const { return isConstantImm() ? isUInt(getConstantImm()) : isImm(); } @@ -1349,6 +1353,11 @@ class MipsOperand : public MCParsedAsmOperand { getConstantImm() <= Top; } + template bool isConstantNegImmRange() const { + return isConstantImm() && getConstantImm() >= -Bottom && + getConstantImm() <= -Top; + } + bool isToken() const override { // Note: It's not possible to pretend that other operand kinds are tokens. // The matcher emitter checks tokens first. diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 391423c4b530a..1fecbb9855212 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -38,6 +38,7 @@ def imm32ZExt12ANDI : Imm.getZExtValue() == 65535; }]>; def imm32ZExt5 : IntImmLeaf(Imm.getZExtValue()); }]>; def imm32SExt12 : IntImmLeaf(Imm.getSExtValue()); }]>; +def imm32Neg12 : IntImmLeaf(Imm.getSExtValue()) && Imm.getSExtValue() < 0; }]>; // True if (N + 1) fits in 12-bit field. def immZExt12Plus1 : PatLeaf<(imm), [{ return isUInt<13>(N->getZExtValue()) && isUInt<12>(N->getZExtValue() + 1); @@ -45,12 +46,35 @@ def immZExt12Plus1 : PatLeaf<(imm), [{ def immZExt7Plus1 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()) && isUInt<12>(N->getZExtValue() + 1); }]>; -// Immediate range covering both signed 12-bit and unsigned 16-bit immediates. +// Immediate range for signed 12-bit def imm32SExt12OrZExt16 : IntImmLeaf(Imm.getSExtValue()) || isUInt<16>(Imm.getZExtValue()); }]>; + +class ConstantSImmRangeAsmOperandClass Supers = []> + : AsmOperandClass { + let Name = "ConstantNegImmRange" # Bottom # "_" # Top; + let RenderMethod = "addSImmOperands<" # 12 # ">"; + let PredicateMethod = "isConstantNegImmRange<" # Bottom # ", " # Top # ">"; + let SuperClasses = Supers; + let DiagnosticType = "SImmRange" # Bottom # "_" # Top; +} + +class NegImmAsmOperandClass Supers = []> + : AsmOperandClass { + let Name = "NegImm" # Bits; + let RenderMethod = "addSImmOperands<" # Bits # ">"; + let PredicateMethod = "isNegImm<" # Bits # ">"; + let SuperClasses = Supers; + let DiagnosticType = "SImm" # Bits; +} + def UImm12AsmOperandClass : UImmAsmOperandClass<12, []>; def UImm5AsmOperandClass : UImmAsmOperandClass<5, [UImm12AsmOperandClass]>; +def SImm12AsmOperandClass : SImmAsmOperandClass<12, []>; +def NImm12AsmOperandClass : NegImmAsmOperandClass<12, []>; +def NaImm12AsmOperandClass : ConstantSImmRangeAsmOperandClass<4095, 1, []>; def UImm3Plus1AsmOperandClass : ConstantUImmAsmOperandClass<3, [UImm5AsmOperandClass], 1>; @@ -66,6 +90,14 @@ def uimm3plus1_nm : Operand { let PrintMethod = "printUImm<3, 1>"; let ParserMatchClass = !cast("UImm3Plus1AsmOperandClass"); } +def nimm12_nm : Operand { + let PrintMethod = "printUImm<12>"; + let ParserMatchClass = !cast("NaImm12AsmOperandClass"); +} +def uimm16_nm : Operand { + let PrintMethod = "printUImm<16>"; + let ParserMatchClass = !cast("SImm16AsmOperandClass"); +} def simm32power2 : IntImmLeaf; @@ -433,11 +465,10 @@ class AddiU32, _Pool_P32<0b00000> { bits<5> rt; bits<5> rs; - bits<12> imm12; bits<16> imm16; let Inst{25...21} = rt; let Inst{20...16} = rs; - let Inst{11...0} = imm12; + let Inst{15...0} = imm16; } class DivMod psel, SDPatternOperator OpNode = null_frag> : From 4e16efcac9b70acb6fe111a4c1296afa5ef6add2 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 9 Oct 2022 16:55:42 -0700 Subject: [PATCH 013/123] Basic decoding logic for 16, 32 & 48-bit nanoMIPS instructions --- .../Mips/Disassembler/MipsDisassembler.cpp | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 76507c49ff625..e5fd0077d8b7a 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -39,12 +39,14 @@ namespace { class MipsDisassembler : public MCDisassembler { bool IsMicroMips; + bool IsNanoMips; bool IsBigEndian; public: MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian) : MCDisassembler(STI, Ctx), IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]), + IsNanoMips(STI.getFeatureBits()[Mips::FeatureNanoMips]), IsBigEndian(IsBigEndian) {} bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; } @@ -588,6 +590,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsDisassembler() { createMipsDisassembler); TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(), createMipselDisassembler); + TargetRegistry::RegisterMCDisassembler(getTheNanoMipsTarget(), + createMipselDisassembler); } #include "MipsGenDisassemblerTables.inc" @@ -1231,6 +1235,31 @@ static DecodeStatus readInstruction32(ArrayRef Bytes, uint64_t Address, return MCDisassembler::Success; } + +/// Read four bytes from the ArrayRef and return 32 bit word sorted +/// according to the given endianness. +static DecodeStatus readInstruction48(ArrayRef Bytes, uint64_t Address, + uint64_t &Size, uint32_t &Insn, uint32_t &Insn2, + bool IsBigEndian = false, bool IsNanoMips = true) { + // We want to read exactly 6 Bytes of little-endian data in nanoMIPS mode. + if (Bytes.size() < 6 || IsBigEndian || !IsNanoMips) { + Size = 0; + return MCDisassembler::Fail; + } + + // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) + // always precede the low 16 bits in the instruction stream (that is, they + // are placed at lower addresses in the instruction stream). + // + // nanoMIPS byte ordering: + // Little-endian: 1 | 0 | 3 | 2 | 5 | 4 + + Insn = (Bytes[4] << 0) | (Bytes[5] << 8) | (Bytes[2] << 16) + | (Bytes[3] << 24); + Insn2 = (Bytes[0] << 32) | (Bytes[1] << 40); + return MCDisassembler::Success; +} + DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef Bytes, uint64_t Address, @@ -1239,6 +1268,59 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, DecodeStatus Result; Size = 0; + if (IsNanoMips) { + uint32_t Insn2; + Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + LLVM_DEBUG( + dbgs() << "Trying NanoMips16 table (16-bit instructions):\n"); + // Calling the auto-generated decoder function for microMIPS32R6 + // 16-bit instructions. + Result = decodeInstruction(DecoderTableNanoMips16, Instr, Insn, + Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 2; + return Result; + } + + Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, IsNanoMips); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + LLVM_DEBUG( + dbgs() << "Trying NanoMips32 table (32-bit instructions):\n"); + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTableNanoMips32, Instr, Insn, + Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + + Result = readInstruction48(Bytes, Address, Size, Insn, Insn2, IsBigEndian, IsNanoMips); + if (Result == MCDisassembler::Fail) + return MCDisassembler::Fail; + + LLVM_DEBUG(dbgs() << "Trying NanoMips48 table (48-bit instructions):\n"); + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTableNanoMips48, Instr, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) { + Size = 6; + return Result; + } + + // This is an invalid instruction. Claim that the Size is 2 bytes. Since + // microMIPS instructions have a minimum alignment of 2, the next 2 bytes + // could form a valid instruction. The two bytes we rejected as an + // instruction could have actually beeen an inline constant pool that is + // unconditionally branched over. + Size = 2; + return MCDisassembler::Fail; + } + if (IsMicroMips) { Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); if (Result == MCDisassembler::Fail) From c4c842fd873c931e15e017ec64f1df4aed032ad7 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 10 Oct 2022 19:37:16 -0700 Subject: [PATCH 014/123] Split encodings and descriptor classes --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 6 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 269 +++++++++++++------- 2 files changed, 173 insertions(+), 102 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 6118f23ca931c..50ff14931bf51 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -123,12 +123,12 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, LAGPB_NM, LSA_NM, MOVEP_NM, MOVE_NM, MOD_NM, MODU_NM, - MUH_NM, MUHU_NM, MUL_NM, MULU_NM, NOT_NM, - NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, + MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MULu4x4_NM, + NOT_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, ROTR_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, SLLV_NM, SLT_NM, SLTI_NM, SLTIU_NM, SLTU_NM, SRAV_NM, SRA_NM, SRLV_NM, SRL_NM, SUB_NM, - SUBu_NM, XOR_NM, XOR16_NM, XORI_NM)>; + SUBu_NM, SUBu16_NM, XOR_NM, XOR16_NM, XORI_NM)>; // MIPS64 // ====== diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 1fecbb9855212..c6147c9e916e4 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -388,26 +388,26 @@ class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { // TODO BC_32 : _Pool_P_BAL<0b0> // 16-bit arithmetic and logical instructions with 4x4 register operands, P16_4X4 -class Arith4x4 isel, - SDPatternOperator OpNode = null_frag>: +class Arith4x4_Desc: InstNM<(outs RO:$dst), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$dst, $rs, $rt"), - [(set RO:$dst, (OpNode RO:$rs, RO:$rt))]>, _Pool_P16_4X4 { + [(set RO:$dst, (OpNode RO:$rs, RO:$rt))]> { let Constraints = "$rt = $dst"; - let isCommutable = 1; Format Form = FrmR; - let AddedComplexity = -1; } +class Arith4x4_Enc isel>: _Pool_P16_4X4; + // 32-bit arithmetic and logical instructions with 3 register operands. -class ArithLogicR32 psel, - SDPatternOperator OpNode = null_frag>: +class ArithLogicR32_Desc: InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), - !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>, _Pool_POOL32A0_0 { + !strconcat(opstr, "\t$rd, $rs, $rt"), + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>; + +class ArithLogicR32_Enc psel>: _Pool_POOL32A0_0 { bits<5> rd; bits<5> rs; bits<5> rt; @@ -417,23 +417,35 @@ class ArithLogicR32 isel, - SDPatternOperator OpNode = null_frag>: - InstNM<(outs RO:$rt), (ins RO:$rs), !strconcat(opstr, "\t$rt, $rs"), - [(set RO:$rt, (OpNode RO:$rs))]>, _Pool_POOL16C_00 { +class ArithLogicR16_Desc: + InstNM<(outs RO:$dst), (ins RO:$rs, RO:$rt), + !strconcat(opstr, "\t$dst, $rs, $rt"), + [(set RO:$dst, (OpNode RO:$rs, RO:$rt))]> { + let Constraints = "$dst = $rt"; +} + +class ArithLogicR16U_Desc: + InstNM<(outs RO:$rt), (ins RO:$rs), + !strconcat(opstr, "\t$rt, $rs"), + [(set RO:$rt, (OpNode RO:$rs))]> { +} + +class ArithLogicR16_Enc isel>: _Pool_POOL16C_00 { bits<3> rs; bits<3> rt; let Inst{9...7} = rt; let Inst{6...4} = rs; } -// 16-bit arithmetic and logical instructions with 2 register operands, POOL16C_0 -class AddSubR16 isel, - SDPatternOperator OpNode = null_frag>: +// 16-bit arithmetic instructions with 2 register operands, POOL16C_0 +class AddSubR16_Desc: InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>, _Pool_P16_ADDU { + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))]>; + +class AddSubR16_Enc isel>: _Pool_P16_ADDU { bits<3> rd; bits<3> rs; bits<3> rt; @@ -446,22 +458,22 @@ class AddSubR16 : + SDPatternOperator imm_type = null_frag, + SDPatternOperator OpNode = null_frag> : InstNM<(outs RO:$rt), (ins RO:$rs, Od:$imm), - !strconcat(opstr, "\t$rt, $rs, $imm"), - [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm))]> { + !strconcat(opstr, "\t$rt, $rs, $imm"), + [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm))]> { let isReMaterializable = 1; } class ArithLogicI32 : + SDPatternOperator imm_type = null_frag, + SDPatternOperator OpNode = null_frag> : ArithLogicINM; class AddiU32 : + SDPatternOperator imm_type = null_frag, + SDPatternOperator OpNode = null_frag> : ArithLogicINM, _Pool_P32<0b00000> { bits<5> rt; bits<5> rs; @@ -471,17 +483,18 @@ class AddiU32 psel, SDPatternOperator OpNode = null_frag> : - ArithLogicR32 { +class DivMod : + ArithLogicR32_Desc { // Need to insert TEQ, because DIV(U)/MOD(U) don't trap on division by zero. bit usesCustomInserter = 1; } -class CondLogicI32 psel, - SDPatternOperator OpNode = null_frag> : - ArithLogicINM, _Pool_P_U12 { +class CondLogicI32_Desc : + ArithLogicINM; + +class CondLogicI32_Enc psel> : _Pool_P_U12 { bits<5> rt; bits<5> rs; bits<12> u12; @@ -490,11 +503,12 @@ class CondLogicI32 psel, SDPatternOperator OpNode = null_frag> : - ArithLogicINM, _Pool_P_SHIFT { + ArithLogicINM; + +class ShiftI32_Enc psel> : _Pool_P_SHIFT { bits<5> rt; bits<5> rs; bits<5> u5; @@ -507,7 +521,7 @@ class ExtBaseNM : InstNM<(outs RO:$rt), (ins RO:$rs, uimm5:$pos, uimm5_plus1:$size), "ext\t$rt, $rs, $pos, $size", [(set RO:$rt, (MipsExt RO:$rs, immZExt5:$pos, immZExt5Plus1:$size))], - II_EXT>, _Pool_P_EXT_INS<0b1111>; + II_EXT>; class InsBaseNM : InstNM<(outs RO:$rt), @@ -515,16 +529,30 @@ class InsBaseNM : "ins \t$rt, $rs, $pos, $size", [(set RO:$rt, (MipsIns RO:$rs, immZExt5:$pos, immZExt5Plus1:$size, RO:$src))], - II_INS>, _Pool_P_EXT_INS<0b1110> { + II_INS>{ let Constraints = "$src = $rt"; } -class Trap isel> : +class ExtInsBase_Enc isel> : _Pool_P_EXT_INS { + bits<5> rt; + bits<5> rs; + bits<5> pos; + bits<5> size; + + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{4...0} = pos; + let Inst{10...6} = size; +} + +class Trap_Desc : InstNM<(outs), (ins RO:$rs, RO:$rt, ImmOp:$imm), - !strconcat(opstr, "\t$rt, $rs, $imm"), []>, - _Pool_P_TRAP { + !strconcat(opstr, "\t$rt, $rs, $imm"), []> { let hasSideEffects = 1; let isCTI = 1; +} + +class Trap_Enc isel> : _Pool_P_TRAP { bits<5> rt; bits<5> rs; bits<5> cd; @@ -540,12 +568,13 @@ class RegImmNM; -class RegImm48 isel, +class RegImm48_Desc : InstNM<(outs RO:$rt), (ins Od:$imm), !strconcat(opstr, "\t$rt, $imm"), - [(set RO:$rt, (OpNode imm_type:$imm))]>, _Pool_P48I { + [(set RO:$rt, (OpNode imm_type:$imm))]>; + +class RegImm48_Enc isel> : _Pool_P48I { bits<5> rt; bits<32> imm; let Inst{41...37} = rt; @@ -725,59 +754,94 @@ class ReverseNM: // 16-bit register operations let FastISelShouldIgnore = 1 in { -def ADDu16_NM : AddSubR16<"addu", GPR3Opnd, 0b0, add>; -//def SUBu16_NM : AddSubR16<"subu", GPR3Opnd, 0b1, sub>; -def ADDu4x4_NM : Arith4x4<"addu", GPR4Opnd, 0b00>; -//def MULu4x4_NM : Arith4x4<"mulu", GPR4Opnd, 0b01, mul>; +def ADDu16_NM : AddSubR16_Desc<"addu16", GPR3Opnd, add>, + AddSubR16_Enc<0b0>; +def SUBu16_NM : AddSubR16_Desc<"subu", GPR3Opnd, sub>, + AddSubR16_Enc<0b1>; +def ADDu4x4_NM : Arith4x4_Desc<"addu4 x4", GPR4Opnd, add>, + Arith4x4_Enc<0b00>; +def MULu4x4_NM : Arith4x4_Desc<"mulu", GPR4Opnd, mul>, + Arith4x4_Enc<0b01>; } // _POOL32A0_0 pool of instructions. -def SLLV_NM : ArithLogicR32<"sllv", GPR32NMOpnd, 0b000010, shl>; -def SRLV_NM : ArithLogicR32<"srlv", GPR32NMOpnd, 0b000110, srl>; -def SRAV_NM : ArithLogicR32<"srav", GPR32NMOpnd, 0b001010, sra>; -def ROTRV_NM : ArithLogicR32<"rotrv", GPR32NMOpnd, 0b001110, rotr>; -def ADD_NM : ArithLogicR32<"add", GPR32NMOpnd, 0b010010>; -def ADDu_NM : ArithLogicR32<"addu", GPR32NMOpnd, 0b010110, add>; - -def SUB_NM : ArithLogicR32<"sub", GPR32NMOpnd, 0b011010>; -def SUBu_NM : ArithLogicR32<"subu", GPR32NMOpnd, 0b011110, sub>; -def AND_NM : ArithLogicR32<"and", GPR32NMOpnd, 0b100110, and>; -def OR_NM : ArithLogicR32<"or", GPR32NMOpnd, 0b101010, or>; -def NOR_NM : ArithLogicR32<"nor", GPR32NMOpnd, 0b101110>; -def XOR_NM : ArithLogicR32<"xor", GPR32NMOpnd, 0b110010, xor>; -def SLT_NM : ArithLogicR32<"slt", GPR32NMOpnd, 0b110110, setlt>; -def SLTU_NM : ArithLogicR32<"sltu", GPR32NMOpnd, 0b111010, setult>; -def MUL_NM : ArithLogicR32<"mul", GPR32NMOpnd, 0b000011, mul>; -def MUH_NM : ArithLogicR32<"muh", GPR32NMOpnd, 0b000111, mulhs>; -def MULU_NM : ArithLogicR32<"mulu", GPR32NMOpnd, 0b001011>; -def MUHU_NM : ArithLogicR32<"muhu", GPR32NMOpnd, 0b001111, mulhu>; -def DIV_NM : DivMod<"div", 0b010011, sdiv>; -def MOD_NM : DivMod<"mod", 0b010111, srem>; -def DIVU_NM : DivMod<"divu", 0b011011, udiv>; -def MODU_NM : DivMod<"modu", 0b011111, urem>; +def SLLV_NM : ArithLogicR32_Desc<"sllv", GPR32NMOpnd, shl>, + ArithLogicR32_Enc<0b000010>; +def SRLV_NM : ArithLogicR32_Desc<"srlv", GPR32NMOpnd, srl>, + ArithLogicR32_Enc<0b000110>; +def SRAV_NM : ArithLogicR32_Desc<"srav", GPR32NMOpnd, sra>, + ArithLogicR32_Enc<0b001010>; +def ROTRV_NM : ArithLogicR32_Desc<"rotrv", GPR32NMOpnd, rotr>, + ArithLogicR32_Enc<0b001110>; +def ADD_NM : ArithLogicR32_Desc<"add", GPR32NMOpnd>, + ArithLogicR32_Enc<0b001110>; +def ADDu_NM : ArithLogicR32_Desc<"addu", GPR32NMOpnd, add>, + ArithLogicR32_Enc<0b010110>; +def SUB_NM : ArithLogicR32_Desc<"sub", GPR32NMOpnd>, + ArithLogicR32_Enc<0b011010>; +def SUBu_NM : ArithLogicR32_Desc<"subu", GPR32NMOpnd, sub>, + ArithLogicR32_Enc<0b011110>; +def AND_NM : ArithLogicR32_Desc<"and", GPR32NMOpnd, and>, + ArithLogicR32_Enc<0b100110>; +def OR_NM : ArithLogicR32_Desc<"or", GPR32NMOpnd, or>, + ArithLogicR32_Enc<0b101010>; +def NOR_NM : ArithLogicR32_Desc<"nor", GPR32NMOpnd>, + ArithLogicR32_Enc<0b101110>; +def XOR_NM : ArithLogicR32_Desc<"xor", GPR32NMOpnd, xor>, + ArithLogicR32_Enc<0b110010>; +def SLT_NM : ArithLogicR32_Desc<"slt", GPR32NMOpnd, setlt>, + ArithLogicR32_Enc<0b110110>; +def SLTU_NM : ArithLogicR32_Desc<"sltu", GPR32NMOpnd, setult>, + ArithLogicR32_Enc<0b111010>; +def MUL_NM : ArithLogicR32_Desc<"mul", GPR32NMOpnd, mul>, + ArithLogicR32_Enc<0b000011>; +def MUH_NM : ArithLogicR32_Desc<"muh", GPR32NMOpnd, mulhs>, + ArithLogicR32_Enc<0b000111>; +def MULU_NM : ArithLogicR32_Desc<"mulu", GPR32NMOpnd>, + ArithLogicR32_Enc<0b001011>; +def MUHU_NM : ArithLogicR32_Desc<"muhu", GPR32NMOpnd, mulhu>, + ArithLogicR32_Enc<0b001111>; +def DIV_NM : DivMod<"div", sdiv>, + ArithLogicR32_Enc<0b010011>; +def MOD_NM : DivMod<"mod", srem>, + ArithLogicR32_Enc<0b010111>; +def DIVU_NM : DivMod<"divu", udiv>, + ArithLogicR32_Enc<0b011011>; +def MODU_NM : DivMod<"modu", urem>, + ArithLogicR32_Enc<0b011111>; // P.U12 pool of instructions -def ORI_NM : CondLogicI32<"ori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0000, or>; -def XORI_NM : CondLogicI32<"xori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0001, xor>; -def ANDI_NM : CondLogicI32<"andi", uimm16, GPR32NMOpnd, imm32ZExt12ANDI, 0b0010, and>; -def SLTI_NM : CondLogicI32<"slti", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0100, setlt>; -def SLTIU_NM : CondLogicI32<"sltiu", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0101, setult>; -def SEQI_NM : CondLogicI32<"seqi", uimm12_nm, GPR32NMOpnd, imm32ZExt12, 0b0110, seteq>; - -// P.SHIFT pool of instructions -def SLL_NM : ShiftI32<"sll", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0000, shl>; -def SRL_NM : ShiftI32<"srl", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0010, srl>; -def SRA_NM : ShiftI32<"sra", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0100, sra>; -def ROTR_NM : ShiftI32<"rotr", uimm5_nm, GPR32NMOpnd, imm32ZExt5, 0b0110, rotr>; +def ORI_NM : CondLogicI32_Desc<"ori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, or>, + CondLogicI32_Enc<0b0000>; +def XORI_NM : CondLogicI32_Desc<"xori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, xor>, + CondLogicI32_Enc<0b0001>; +def ANDI_NM : CondLogicI32_Desc<"andi", uimm16, GPR32NMOpnd, imm32ZExt12ANDI, and>, + CondLogicI32_Enc<0b0010>; +def SLTI_NM : CondLogicI32_Desc<"slti", uimm12_nm, GPR32NMOpnd, imm32ZExt12, setlt>, + CondLogicI32_Enc<0b0100>; +def SLTIU_NM : CondLogicI32_Desc<"sltiu", uimm12_nm, GPR32NMOpnd, imm32ZExt12, setult>, + CondLogicI32_Enc<0b0101>; +def SEQI_NM : CondLogicI32_Desc<"seqi", uimm12_nm, GPR32NMOpnd, imm32ZExt12, seteq>, + CondLogicI32_Enc<0b0110>; -def EXT_NM : ExtBaseNM; -def INS_NM : InsBaseNM; +// P.SHIFT pool of instructions +def SLL_NM : ShiftI32_Desc<"sll", uimm5_nm, GPR32NMOpnd, imm32ZExt5, shl>, + ShiftI32_Enc<0b0000>; +def SRL_NM : ShiftI32_Desc<"srl", uimm5_nm, GPR32NMOpnd, imm32ZExt5, srl>, + ShiftI32_Enc<0b0010>; +def SRA_NM : ShiftI32_Desc<"sra", uimm5_nm, GPR32NMOpnd, imm32ZExt5, sra>, + ShiftI32_Enc<0b0100>; +def ROTR_NM : ShiftI32_Desc<"rotr", uimm5_nm, GPR32NMOpnd, imm32ZExt5, rotr>, + ShiftI32_Enc<0b0110>; + +def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; +def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPR32NMOpnd, imm32SExt12OrZExt16, add>; let Constraints = "$rt = $rs" in def ADDIU48_NM : ArithLogicINM<"addiu[48]", simm32_relaxed, GPR32NMOpnd, - imm32_NM, add>, _Pool_P48I<0b00001>; + imm32_NM, add>, RegImm48_Enc<0b00001>; def LSA_NM : LoadScaledAddressNM<"lsa", GPR32NMOpnd>; @@ -791,13 +855,17 @@ def BITREVW_NM : ReverseNM<"bitrevw", GPR32NMOpnd, bitreverse>; def BYTEREVW_NM : ReverseNM<"byterevw", GPR32NMOpnd, bswap>; // P.TRAP pool of instructions. -def TEQ_NM : Trap<"teq", GPR32NMOpnd, uimm5_nm, 0b0>; -def TNE_NM : Trap<"tne", GPR32NMOpnd, uimm5_nm, 0b1>; - -def NOT_NM : ArithLogicR16<"not", GPR3Opnd, 0b00, not>; -def XOR16_NM : ArithLogicR16<"xor16", GPR3Opnd, 0b01>; -def AND16_NM : ArithLogicR16<"and16", GPR3Opnd, 0b10>; -def OR16_NM : ArithLogicR16<"or16", GPR3Opnd, 0b11>; +def TEQ_NM : Trap_Desc<"teq", GPR32NMOpnd, uimm5_nm>, Trap_Enc<0b0>; +def TNE_NM : Trap_Desc<"tne", GPR32NMOpnd, uimm5_nm>, Trap_Enc<0b1>; + +def NOT_NM : ArithLogicR16U_Desc<"not16", GPR3Opnd, not>, + ArithLogicR16_Enc<0b00>; +def XOR16_NM : ArithLogicR16_Desc<"xor16", GPR3Opnd>, + ArithLogicR16_Enc<0b01>; +def AND16_NM : ArithLogicR16_Desc<"and16", GPR3Opnd>, + ArithLogicR16_Enc<0b10>; +def OR16_NM : ArithLogicR16_Desc<"or16", GPR3Opnd>, + ArithLogicR16_Enc<0b11>; def JRC_NM : IndirectBranchNM<"jrc", GPR32NMOpnd>; @@ -805,10 +873,13 @@ def BALC_NM : CallNM<"balc", MipsJmpLink, tglobaladdr>, InstSize32; def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { -def Li_NM : RegImm48<"li", simm32_relaxed, GPR32NMOpnd, 0b00000>; -def LA_NM : RegImm48<"la", simm32_relaxed, GPR32NMOpnd, 0b00011>; +def Li_NM : RegImm48_Desc<"li", simm32_relaxed, GPR32NMOpnd>, + RegImm48_Enc<0b00000>; +def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPR32NMOpnd>, + RegImm48_Enc<0b00011>; -def LAGPB_NM : RegImm48<"addiu.b", simm32_relaxed, GPR32NMOpnd, 0b00010> { +def LAGPB_NM : RegImm48_Desc<"addiu.b", simm32_relaxed, GPR32NMOpnd>, + RegImm48_Enc<0b00010> { let AsmString = "addiu.b $rt, $$gp, %gprel( $imm )"; let isReMaterializable = 1; } From d2d284d0ceb3bab64467598f71a0276aaa5db31f Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 10 Oct 2022 23:36:42 -0700 Subject: [PATCH 015/123] Fix immediate operand name in encoding classes --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index c6147c9e916e4..7745e3a383ac7 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -477,10 +477,10 @@ class AddiU32, _Pool_P32<0b00000> { bits<5> rt; bits<5> rs; - bits<16> imm16; + bits<16> imm; let Inst{25...21} = rt; let Inst{20...16} = rs; - let Inst{15...0} = imm16; + let Inst{15...0} = imm; } class DivMod : @@ -497,10 +497,10 @@ class CondLogicI32_Desc psel> : _Pool_P_U12 { bits<5> rt; bits<5> rs; - bits<12> u12; + bits<12> imm; let Inst{25...21} = rt; let Inst{20...16} = rs; - let Inst{11...0} = u12; + let Inst{11...0} = imm; } class ShiftI32_Desc psel> : _Pool_P_SHIFT { bits<5> rt; bits<5> rs; - bits<5> u5; + bits<5> imm; let Inst{25...21} = rt; let Inst{20...16} = rs; - let Inst{4...0} = u5; + let Inst{4...0} = imm; } class ExtBaseNM : @@ -555,10 +555,10 @@ class Trap_Desc : class Trap_Enc isel> : _Pool_P_TRAP { bits<5> rt; bits<5> rs; - bits<5> cd; + bits<5> imm; let Inst{25...21} = rt; let Inst{20...16} = rs; - let Inst{15...11} = cd; + let Inst{15...11} = imm; } // Instructions with 1 register (dest) and 1 immediate operand. From f46fad0828968d4625f3d653d531ec211478bfe0 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Thu, 13 Oct 2022 13:45:37 -0700 Subject: [PATCH 016/123] Add encodings for load/store instructions --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 178 ++++++++++++++++------ 1 file changed, 134 insertions(+), 44 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 7745e3a383ac7..11614f12d5f9f 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -385,6 +385,11 @@ class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { let Inst{5...3} = psel; } +class _Pool_PP_LSX isel> : _Pool_POOL32A7<0b000> { + let Inst{6} = scaled; + let Inst{10...7} = isel; +} + // TODO BC_32 : _Pool_P_BAL<0b0> // 16-bit arithmetic and logical instructions with 4x4 register operands, P16_4X4 @@ -595,6 +600,55 @@ class LoadMemoryNM psel, bits<4> isel> : _Pool_P_LS_S9 +{ + bits<5> rt; + bits<14> addr; + bits<5> base = addr{13...9}; + bits<9> offset = addr{8...0}; + let Inst{25...21} = rt; + let Inst{20...16} = base; + let Inst{14...11} = isel; + let Inst{15} = offset{8}; + let Inst{7...0} = offset{7...0}; +} + +class LSMem_S9_Mult_Enc isel> : _Pool_P_LS_S9 +{ + bits<5> rt; + bits<14> addr; + bits<5> base = addr{13...9}; + bits<9> offset = addr{8...0}; + bits<3> count; + let Inst{25...21} = rt; + let Inst{20...16} = base; + let Inst{11} = isel{3}; + let Inst{15} = offset{8}; + let Inst{7...0} = offset{7...0}; + let Inst{14...12} = count; +} + +class LSMem_U12_Enc isel> : _Pool_P_LS_U12 +{ + bits<5> rt; + bits<17> addr; + bits<5> base = addr{16...12}; + bits<12> offset = addr{11...0}; + let Inst{25...21} = rt; + let Inst{20...16} = base; + let Inst{11...0} = offset; +} + +class LSMemX_Enc isel> : _Pool_PP_LSX +{ + bits<5> rt; + bits<5> rs; + bits<5> rd; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...11} = rd; +} + class StoreMemoryNM, InstSize32; class LoadMultipleNM : InstNM<(outs GPR32NMOpnd:$rt), (ins mem:$addr, uimm3plus1_nm:$count), - !strconcat(opstr, "\t$rt, $addr, $count"), []>, InstSize32 { + !strconcat(opstr, "\t$rt, $addr, $count"), []> { let DecoderMethod = "DecodeMem"; let mayLoad = 1; } class StoreMultipleNM : InstNM<(outs), (ins GPR32NMOpnd:$rt, mem:$addr, uimm3plus1_nm:$count), - !strconcat(opstr, "\t$rt, $addr, $count"), []>, InstSize32 { + !strconcat(opstr, "\t$rt, $addr, $count"), []> { let DecoderMethod = "DecodeMem"; let mayStore = 1; } @@ -702,7 +756,7 @@ class UnalignedLoad : InstNM<(outs RO:$rt), (ins mem_simm9:$addr, RO:$src), !strconcat(opstr, "\t$rt, $addr"), - [(set RO:$rt, (OpNode addrsimm9:$addr, RO:$src))]>, InstSize32 { + [(set RO:$rt, (OpNode addrsimm9:$addr, RO:$src))]> { let DecoderMethod = "DecodeMem"; string Constraints = "$src = $rt"; let mayLoad = 1; @@ -713,7 +767,7 @@ class UnalignedStore : InstNM<(outs), (ins RO:$rt, mem_simm9:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RO:$rt, addrsimm9:$addr)]>, InstSize32 { + [(OpNode RO:$rt, addrsimm9:$addr)]> { let DecoderMethod = "DecodeMem"; let mayStore = 1; } @@ -1123,59 +1177,95 @@ def : NMPat<(brcond (i32 (seteq (and GPR32NM:$rt, simm32power2:$imm), 0)), bb:$o // //===----------------------------------------------------------------------===// -let isCodeGenOnly = 1 in { // TODO: addruimm12 and addrsimm9 need to be looked into again. Currently // addruimm12 needs to come before addrsimm9, because addrsimm9 handles // loads/store that do not fit the offset. If we put the same handling in // addruimm12, this will cause addrsimm9 to never get selected. -def LWs9_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem, load, addrsimm9, II_LW>, InstSize32; -def LW_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem, load, addruimm12, II_LW>, InstSize32; -def LWXS_NM : LoadMemoryNM<"lwxs", GPR32NMOpnd, mem, load, addrindexedlsl2, II_LW>, InstSize32; -def LWX_NM : LoadMemoryNM<"lwx", GPR32NMOpnd, mem, load, addrindexed, II_LW>, InstSize32; -def SW_NM : StoreMemoryNM<"sw", GPR32NMOpnd, mem, store, addruimm12, II_SW>, InstSize32; -def SWs9_NM : StoreMemoryNM<"sw", GPR32NMOpnd, mem, store, addrsimm9, II_SW>, InstSize32; -def SWXS_NM : StoreMemoryNM<"swxs", GPR32NMOpnd, mem, store, addrindexedlsl2, II_SW>, InstSize32; -def SWX_NM : StoreMemoryNM<"swx", GPR32NMOpnd, mem, store, addrindexed, II_SW>, InstSize32; - -def LHU_NM : LoadMemoryNM<"lhu", GPR32NMOpnd, mem, zextloadi16, addruimm12, II_LHU>, InstSize32; -def LHUs9_NM : LoadMemoryNM<"lhu", GPR32NMOpnd, mem, zextloadi16, addrsimm9, II_LHU>, InstSize32; -def LHUXS_NM : LoadMemoryNM<"lhuxs", GPR32NMOpnd, mem, zextloadi16, addrindexedlsl1, II_LHU>, InstSize32; -def LHUX_NM : LoadMemoryNM<"lhux", GPR32NMOpnd, mem, zextloadi16, addrindexed, II_LHU>, InstSize32; -def LH_NM : LoadMemoryNM<"lh", GPR32NMOpnd, mem, sextloadi16, addruimm12, II_LH>, InstSize32; -def LHs9_NM : LoadMemoryNM<"lh", GPR32NMOpnd, mem, sextloadi16, addrsimm9, II_LH>, InstSize32; -def LHXS_NM : LoadMemoryNM<"lhxs", GPR32NMOpnd, mem, sextloadi16, addrindexedlsl1, II_LH>, InstSize32; -def LHX_NM : LoadMemoryNM<"lhx", GPR32NMOpnd, mem, sextloadi16, addrindexed, II_LH>, InstSize32; -def SH_NM : StoreMemoryNM<"sh", GPR32NMOpnd, mem, truncstorei16, addruimm12, II_SH>, InstSize32; -def SHs9_NM : StoreMemoryNM<"sh", GPR32NMOpnd, mem, truncstorei16, addrsimm9, II_SH>, InstSize32; -def SHXS_NM : StoreMemoryNM<"shxs", GPR32NMOpnd, mem, truncstorei16, addrindexedlsl1, II_SH>, InstSize32; -def SHX_NM : StoreMemoryNM<"shx", GPR32NMOpnd, mem, truncstorei16, addrindexed, II_SH>, InstSize32; - -def LBU_NM : LoadMemoryNM<"lbu", GPR32NMOpnd, mem, zextloadi8, addruimm12, II_LBU>, InstSize32; -def LBUs9_NM : LoadMemoryNM<"lbu", GPR32NMOpnd, mem, zextloadi8, addrsimm9, II_LBU>, InstSize32; -def LBUX_NM : LoadMemoryNM<"lbux", GPR32NMOpnd, mem, zextloadi8, addrindexed, II_LBU>, InstSize32; -def LB_NM : LoadMemoryNM<"lb", GPR32NMOpnd, mem, sextloadi8, addruimm12, II_LB>, InstSize32; -def LBs9_NM : LoadMemoryNM<"lb", GPR32NMOpnd, mem, sextloadi8, addrsimm9, II_LB>, InstSize32; -def LBX_NM : LoadMemoryNM<"lbx", GPR32NMOpnd, mem, sextloadi8, addrindexed, II_LB>, InstSize32; -def SB_NM : StoreMemoryNM<"sb", GPR32NMOpnd, mem, truncstorei8, addruimm12, II_SB>, InstSize32; -def SBs9_NM : StoreMemoryNM<"sb", GPR32NMOpnd, mem, truncstorei8, addrsimm9, II_SB>, InstSize32; -def SBX_NM : StoreMemoryNM<"sbx", GPR32NMOpnd, mem, truncstorei8, addrindexed, II_SB>, InstSize32; +def LB_NM : LoadMemoryNM<"lb", GPR32NMOpnd, mem, sextloadi8, addruimm12, II_LB>, + LSMem_U12_Enc<0b0000>; +def SB_NM : StoreMemoryNM<"sb", GPR32NMOpnd, mem, truncstorei8, addruimm12, II_SB>, + LSMem_U12_Enc<0b0001>; +def LH_NM : LoadMemoryNM<"lh", GPR32NMOpnd, mem, sextloadi16, addruimm12, II_LH>, + LSMem_U12_Enc<0b0100>; +def SH_NM : StoreMemoryNM<"sh", GPR32NMOpnd, mem, truncstorei16, addruimm12, II_SH>, + LSMem_U12_Enc<0b0101>; +def LW_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem, load, addruimm12, II_LW>, + LSMem_U12_Enc<0b1000>; +def SW_NM : StoreMemoryNM<"sw", GPR32NMOpnd, mem, store, addruimm12, II_SW>, + LSMem_U12_Enc<0b1001>; +def LBU_NM : LoadMemoryNM<"lbu", GPR32NMOpnd, mem, zextloadi8, addruimm12, II_LBU>, + LSMem_U12_Enc<0b0010>; +def LHU_NM : LoadMemoryNM<"lhu", GPR32NMOpnd, mem, zextloadi16, addruimm12, II_LHU>, + LSMem_U12_Enc<0b0110>; + +def LBs9_NM : LoadMemoryNM<"lb", GPR32NMOpnd, mem, sextloadi8, addrsimm9, II_LB>, + LSMem_S9_Enc<0b000, 0b0000>; +def SBs9_NM : StoreMemoryNM<"sb", GPR32NMOpnd, mem, truncstorei8, addrsimm9, II_SB>, + LSMem_S9_Enc<0b000, 0b0001>; +def LHs9_NM : LoadMemoryNM<"lh", GPR32NMOpnd, mem, sextloadi16, addrsimm9, II_LH>, + LSMem_S9_Enc<0b000, 0b0100>; +def SHs9_NM : StoreMemoryNM<"sh", GPR32NMOpnd, mem, truncstorei16, addrsimm9, II_SH>, + LSMem_S9_Enc<0b000, 0b0101>; +def LWs9_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem, load, addrsimm9, II_LW>, + LSMem_S9_Enc<0b000, 0b1000>; +def SWs9_NM : StoreMemoryNM<"sw", GPR32NMOpnd, mem, store, addrsimm9, II_SW>, + LSMem_S9_Enc<0b000, 0b1001>; +def LBUs9_NM : LoadMemoryNM<"lbu", GPR32NMOpnd, mem, zextloadi8, addrsimm9, II_LBU>, + LSMem_S9_Enc<0b000, 0b0010>; +def LHUs9_NM : LoadMemoryNM<"lhu", GPR32NMOpnd, mem, zextloadi16, addrsimm9, II_LHU>, + LSMem_S9_Enc<0b000, 0b0110>; + +def LBX_NM : LoadMemoryNM<"lbx", GPR32NMOpnd, mem, sextloadi8, addrindexed, II_LB>, + LSMemX_Enc<0, 0b0000>; +def SBX_NM : StoreMemoryNM<"sbx", GPR32NMOpnd, mem, truncstorei8, addrindexed, II_SB>, + LSMemX_Enc<0, 0b0001>; +def LHX_NM : LoadMemoryNM<"lhx", GPR32NMOpnd, mem, sextloadi16, addrindexed, II_LH>, + LSMemX_Enc<0, 0b0100>; +def SHX_NM : StoreMemoryNM<"shx", GPR32NMOpnd, mem, truncstorei16, addrindexed, II_SH>, + LSMemX_Enc<0, 0b0101>; +def LWX_NM : LoadMemoryNM<"lwx", GPR32NMOpnd, mem, load, addrindexed, II_LW>, + LSMemX_Enc<0, 0b1000>; +def SWX_NM : StoreMemoryNM<"swx", GPR32NMOpnd, mem, store, addrindexed, II_SW>, + LSMemX_Enc<0, 0b1001>; +def LBUX_NM : LoadMemoryNM<"lbux", GPR32NMOpnd, mem, zextloadi8, addrindexed, II_LBU>, + LSMemX_Enc<0, 0b0010>; +def LHUX_NM : LoadMemoryNM<"lhux", GPR32NMOpnd, mem, zextloadi16, addrindexed, II_LHU>, + LSMemX_Enc<0, 0b0000>; + +def LHXS_NM : LoadMemoryNM<"lhxs", GPR32NMOpnd, mem, sextloadi16, addrindexedlsl1, II_LH>, + LSMemX_Enc<0b1, 0b0100>; +def SHXS_NM : StoreMemoryNM<"shxs", GPR32NMOpnd, mem, truncstorei16, addrindexedlsl1, II_SH>, + LSMemX_Enc<0b1, 0b0101>; +def LHUXS_NM : LoadMemoryNM<"lhuxs", GPR32NMOpnd, mem, zextloadi16, addrindexedlsl1, II_LHU>, + LSMemX_Enc<0b1, 0b0110>; +def LWXS_NM : LoadMemoryNM<"lwxs", GPR32NMOpnd, mem, load, addrindexedlsl2, II_LW>, + LSMemX_Enc<0b1, 0b1000>; +def SWXS_NM : StoreMemoryNM<"swxs", GPR32NMOpnd, mem, store, addrindexedlsl2, II_SW>, + LSMemX_Enc<0b1, 0b1001>; + + +def UALH_NM : UnalignedLoad<"ualh", NMUnalignedLH>, LSMem_S9_Enc<0b001, 0b0100>; +def UASH_NM : UnalignedStore<"uash", NMUnalignedSH>, LSMem_S9_Enc<0b001, 0b0101>; +def LWM_NM : LoadMultipleNM<"lwm">, LSMem_S9_Mult_Enc<0b0100>; +def UALWM_NM : LoadMultipleNM<"ualwm">, LSMem_S9_Mult_Enc<0b0101>; +def SWM_NM : StoreMultipleNM<"swm">, LSMem_S9_Mult_Enc<0b1100>; +def UASWM_NM : StoreMultipleNM<"uaswm">, LSMem_S9_Mult_Enc<0b1101>; + +def UALW_NM : UnalignedLoad<"ualw", NMUnalignedLW>, LSMem_S9_Enc<0b101, 0b1000>; +def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000>; + +//def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; + +let isCodeGenOnly = 1 in { // TODO: Halfword load/store is never selected, this needs to be looked into. -def UALH_NM : UnalignedLoad<"ualh", NMUnalignedLH>; -def UALW_NM : UnalignedLoad<"ualw", NMUnalignedLW>; -def UASH_NM : UnalignedStore<"uash", NMUnalignedSH>; -def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>; def LWGP_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem>, InstSize32; def SWPC_NM : StorePCBase; def LWPC_NM : LoadPCBase; -def LWM_NM : LoadMultipleNM<"lwm">; -def UALWM_NM : LoadMultipleNM<"ualwm">; -def SWM_NM : StoreMultipleNM<"swm">; -def UASWM_NM : StoreMultipleNM<"uaswm">; def MOVE_NM : InstNM<(outs GPR32NMOpnd:$rt), (ins GPR32NMOpnd:$rs), "move\t$rt, $rs", []>, InstSize16; From a29f8848bbfd73920b67ca08cf304f6e65e3f790 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 22 Oct 2022 09:20:24 -0700 Subject: [PATCH 017/123] Split encoding of 48-bit instructions from descriptors --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 11614f12d5f9f..4d431fd136a0c 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -661,15 +661,21 @@ class StoreMemoryNM isel> : _Pool_P48I { + bits<5> rt; + bits<32> addr; + let Inst{41...37} = rt; + let Inst{31...16} = addr{15...0}; + let Inst{15...0} = addr{31...16}; +} + class LoadPCBase : - InstNM<(outs RO:$rt), (ins MO:$addr), "lwpc\t$rt, $addr", [], II_LW>, - InstSize48 { + InstNM<(outs RO:$rt), (ins MO:$addr), "lwpc\t$rt, $addr", [], II_LW> { let mayLoad = 1; } class StorePCBase : - InstNM<(outs), (ins RO:$rt, MO:$addr), "swpc\t$rt, $addr", [], II_SW>, - InstSize48 { + InstNM<(outs), (ins RO:$rt, MO:$addr), "swpc\t$rt, $addr", [], II_SW> { let mayStore = 1; } @@ -1257,16 +1263,15 @@ def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000> //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; +def SWPC_NM : StorePCBase, LSMem_PC48_Enc<0b01011>; +def LWPC_NM : LoadPCBase, LSMem_PC48_Enc<0b01111>; + let isCodeGenOnly = 1 in { // TODO: Halfword load/store is never selected, this needs to be looked into. def LWGP_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem>, InstSize32; -def SWPC_NM : StorePCBase; -def LWPC_NM : LoadPCBase; - - def MOVE_NM : InstNM<(outs GPR32NMOpnd:$rt), (ins GPR32NMOpnd:$rs), "move\t$rt, $rs", []>, InstSize16; def MOVEP_NM : InstNM<(outs GPR32NMOpnd:$dst1, GPR32NMOpnd:$dst2), From 555fede65bdd0e22fda513c0f5e895dfc0830f87 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Wed, 26 Oct 2022 20:11:05 -0700 Subject: [PATCH 018/123] Add load/store variations --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 25 ++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 83 ++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 18 ++ llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 18 ++ llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 9 + llvm/lib/Target/Mips/MipsInstrInfo.td | 18 ++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 16 ++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 6 + llvm/lib/Target/Mips/MipsScheduleGeneric.td | 7 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 252 ++++++++++++++---- 10 files changed, 392 insertions(+), 60 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 34454f0b1a614..45815a1cd8acd 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1370,6 +1370,31 @@ class MipsOperand : public MCParsedAsmOperand { return isMem() && isa(getMemOff()); } + template + bool isMemWithUimmOffset() const { + if (!isMem()) + return false; + if (!getMemBase()->isGPRAsmReg()) + return false; + if ((isConstantMemOff() && + isShiftedUInt(getConstantMemOff()))) + return true; + return false; + MCValue Res; + bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + return IsReloc && isShiftedUInt(Res.getConstant()); + } + + bool isMemRx() const { + if (!isMem()) + return false; + if (!getMemBase()->isGPRAsmReg() + || (getConstantMemOff() < 0) + || (getConstantMemOff() > 31)) + return false; + return true; + } + // Allow relocation operators. template bool isMemWithSimmOffset() const { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 4b8b7ebd40a79..5a0ea6cff057e 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -830,6 +830,23 @@ getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, return OffBits & 0x1F; } +unsigned MipsMCCodeEmitter:: +getMemEncodingNMRX(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Register is encoded in bits 9-5, offset is encoded in bits 4-0. + assert(MI.getOperand(OpNo).isReg()); + assert(MI.getOperand(OpNo+1).isReg()); + + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 5; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), + Fixups, STI); + + return RegBits | OffBits; +} + + unsigned MipsMCCodeEmitter:: getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, @@ -935,6 +952,72 @@ getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, return ((OffBits >> 2) & 0x0F); } +unsigned MipsMCCodeEmitter:: +getMemEncodingNMImm12(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 12; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0xFFF) | RegBits; +} + + +unsigned MipsMCCodeEmitter:: +getMemEncodingNMImm9(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 9; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0x1FF) | RegBits; +} + +unsigned MipsMCCodeEmitter:: +getMemEncodingNMImm6S2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 11-7, offset is encoded in bits 6-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 6; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0x3C) | RegBits; +} + +unsigned MipsMCCodeEmitter:: +getMemEncodingNMImm3S1(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 11-7, offset is encoded in bits 6-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 3; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0x6) | RegBits; +} + +unsigned MipsMCCodeEmitter:: +getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 11-7, offset is encoded in bits 6-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 2; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0x3) | RegBits; +} + // FIXME: should be called getMSBEncoding // unsigned diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index d10e8194f2e5e..02e9a6ab43804 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -223,6 +223,24 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMImm9(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMImm12(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMImm6S2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMImm3S1(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMRX(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; /// Subtract Offset then encode as a N-bit unsigned integer. template diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 233068f83be0b..5a64da746afd7 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -171,6 +171,24 @@ bool MipsDAGToDAGISel::selectIntAddrUImm12(SDValue Addr, SDValue &Base, return false; } +bool MipsDAGToDAGISel::selectIntAddrUImm6s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddrUImm3s1(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + bool MipsDAGToDAGISel::selectIntAddrIndexed(SDValue Addr, SDValue &Base, SDValue &Offset) const { diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 16eea26f2feb3..2702a15c1ec18 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -104,6 +104,15 @@ class MipsDAGToDAGISel : public SelectionDAGISel { virtual bool selectIntAddrUImm12(SDValue Addr, SDValue &Base, SDValue &Offset) const; + virtual bool selectIntAddrUImm6s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + + virtual bool selectIntAddrUImm3s1(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + + virtual bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + virtual bool selectIntAddrIndexed(SDValue Addr, SDValue &Base, SDValue &Offset) const; virtual bool selectIntAddrIndexedLsl2(SDValue Addr, SDValue &Base, SDValue &Offset) const; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 6485f4866e28a..3da36234ed5bd 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1116,6 +1116,24 @@ def MipsMemSimmPtrAsmOperand : AsmOperandClass { let DiagnosticType = "MemSImmPtr"; } +class MipsMemUimmAsmOperand : AsmOperandClass { + let Name = "MemOffsetUimm" # Width # "_" # Shift; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithUimmOffset<" # Width # ", " # Shift # ">"; + let DiagnosticType = !if(!eq(Shift, 0), "MemUImm" # Width, + "MemUImm" # Width # "Lsl" # Shift); +} + +def MipsMemRxAsmOperand : AsmOperandClass { + let Name = "MemRx"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemRx"; +} + def MipsInvertedImmoperand : AsmOperandClass { let Name = "InvNum"; let RenderMethod = "addImmOperands"; diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index eac9bec5f5f3b..a7f803f7adb4c 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -544,6 +544,22 @@ bool MipsSEDAGToDAGISel::selectIntAddrUImm12(SDValue Addr, SDValue &Base, return selectAddrFrameIndexUOffset(Addr, Base, Offset, 12, 0); } + +bool MipsSEDAGToDAGISel::selectIntAddrUImm6s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 4, 2); +} + +bool MipsSEDAGToDAGISel::selectIntAddrUImm3s1(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 2, 1); +} + +bool MipsSEDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 2); +} + // A load/store 'x' indexed (reg + reg) bool MipsSEDAGToDAGISel::selectIntAddrIndexed(SDValue Addr, SDValue &Base, SDValue &Offset) const { diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index e0af0436002bc..8f2b48b3daf42 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -108,6 +108,12 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel { bool selectIntAddrIndexedLsl2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + bool selectIntAddrUImm6s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + + bool selectIntAddrUImm3s1(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + + bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + /// Select constant vector splats. bool selectVSplat(SDNode *N, APInt &Imm, unsigned MinSizeInBits) const override; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 50ff14931bf51..327409a2239ef 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -712,11 +712,12 @@ def : InstRW<[GenericWriteLoad], (instrs LW_NM, LWGP_NM, LWs9_NM, LHX_NM, LHXS_NM, LBUX_NM, LBX_NM, RESTOREJRC_NM, RESTORE_NM, SAVE_NM, UALH_NM, UALW_NM, LWM_NM, UALWM_NM, - LWPC_NM)>; + LWPC_NM, LW16_NM, LH16_NM, LHU16_NM, + LB16_NM, LBU16_NM)>; -def: InstRW<[GenericWriteStore], (instrs SW_NM, SWs9_NM, +def: InstRW<[GenericWriteStore], (instrs SW_NM, SWs9_NM, SW16_NM, SH16_NM, SH_NM, SHs9_NM, - SB_NM, SBs9_NM, + SB_NM, SBs9_NM, SB16_NM, SWX_NM, SWXS_NM, SHX_NM, SHXS_NM, SBX_NM, UASH_NM, UASW_NM, SWM_NM, UASWM_NM, SWPC_NM)>; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 4d431fd136a0c..159401c8e6c1a 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -99,6 +99,41 @@ def uimm16_nm : Operand { let ParserMatchClass = !cast("SImm16AsmOperandClass"); } +def mem_nms9 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm9"; + let ParserMatchClass = MipsMemSimmAsmOperand<9>; +} + +def mem_nmu12 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm12"; + let ParserMatchClass = MipsMemUimmAsmOperand<12>; +} + +def mem_nmpcrel : mem_generic { + let EncoderMethod = "getMemEncodingNMImm9"; + let ParserMatchClass = MipsMemSimmAsmOperand<9>; +} + +def mem_nmrx : mem_generic { + let EncoderMethod = "getMemEncodingNMRX"; + let ParserMatchClass = MipsMemRxAsmOperand; +} + +def mem_nm6s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm6S2"; + let ParserMatchClass = MipsMemUimmAsmOperand<4,2>; +} + +def mem_nm3s1 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm3S1"; + let ParserMatchClass = MipsMemUimmAsmOperand<2,1>; +} + +def mem_nm2 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm2"; + let ParserMatchClass = MipsMemUimmAsmOperand<2>; +} + def simm32power2 : IntImmLeaf; def uimm16_simm12 : Operand; @@ -108,6 +143,9 @@ def addruimm12 : ComplexPattern; def addrindexed : ComplexPattern; def addrindexedlsl1 : ComplexPattern; def addrindexedlsl2 : ComplexPattern; +def addruimm6s2 : ComplexPattern; +def addruimm3s1 : ComplexPattern; +def addruimm2 : ComplexPattern; def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N->getZExtValue()), SDLoc(N), MVT::i32); @@ -587,19 +625,6 @@ class RegImm48_Enc isel> : _Pool_P48I { let Inst{15...0} = imm{31...16}; } -class LoadMemoryNM : - InstNM<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RO:$rt, (OpNode Addr:$addr))], - itin> { - let DecoderMethod = "DecodeMem"; - let canFoldAsLoad = 1; - let mayLoad = 1; - string BaseOpcode = opstr; -} - class LSMem_S9_Enc psel, bits<4> isel> : _Pool_P_LS_S9 { bits<5> rt; @@ -641,20 +666,118 @@ class LSMem_U12_Enc isel> : _Pool_P_LS_U12 class LSMemX_Enc isel> : _Pool_PP_LSX { - bits<5> rt; - bits<5> rs; bits<5> rd; - let Inst{25...21} = rt; - let Inst{20...16} = rs; + bits<5> index; + bits<5> base; + let Inst{25...21} = base; + let Inst{20...16} = index; let Inst{15...11} = rd; } -class StoreMemoryNM isel> : _Pool_P16 +{ + bits<3> rt; + bits<9> addr; + bits<3> base = addr{8...6}; + bits<4> offset = addr{5...2}; + let Inst{9...7} = rt; + let Inst{6...4} = base; + let Inst{3...0} = offset; +} + +class LHMem16_Enc isel> : _Pool_P16_LH +{ + bits<3> rt; + bits<6> addr; + bits<3> base = addr{5...3}; + bits<3> offset = addr{2...0}; + let Inst{9...7} = rt; + let Inst{6...4} = base; + let Inst{2...1} = offset{2...1}; +} + +class LBMem16_Enc isel> : _Pool_P16_LB +{ + bits<3> rt; + bits<5> addr; + bits<3> base = addr{4...2}; + bits<2> offset = addr{1...0}; + let Inst{9...7} = rt; + let Inst{6...4} = base; + let Inst{1...0} = offset{1...0}; +} + +class LoadMemoryNM : + InstNM<(outs GPR32NMOpnd:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set GPR32NMOpnd:$rt, (OpNode Addr:$addr))], + itin> { + let DecoderMethod = "DecodeMem"; + let canFoldAsLoad = 1; + let mayLoad = 1; + string BaseOpcode = opstr; +} + +class LoadMemoryX : + InstNM<(outs GPR32NMOpnd:$rd), (ins PtrRC:$base, PtrRC:$index), + !strconcat(opstr, "\t$rd, ${index}(${base})"), + [], + itin> { + let DecoderMethod = "DecodeMem"; + let canFoldAsLoad = 1; + let mayLoad = 1; + string BaseOpcode = opstr; +} + +class StoreMemoryX : - InstNM<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RO:$rt, Addr:$addr)], + InstNM<(outs), (ins GPR32NMOpnd:$rd, PtrRC:$base, PtrRC:$index), + !strconcat(opstr, "\t$rd, ${index}(${base})"), + [], + itin> { + let DecoderMethod = "DecodeMem"; + let mayStore = 1; + string BaseOpcode = opstr; +} + +class LoadMemoryNM16 : + InstNM<(outs GPR3Opnd:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set GPR3Opnd:$rt, (OpNode Addr:$addr))], + itin> { + let DecoderMethod = "DecodeMem"; + let canFoldAsLoad = 1; + let mayLoad = 1; + string BaseOpcode = opstr; +} + +class StoreMemoryNM : + InstNM<(outs), (ins GPR32NMOpnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode GPR32NMOpnd:$rt, Addr:$addr)], + itin> { + let DecoderMethod = "DecodeMem"; + let mayStore = 1; + string BaseOpcode = opstr; +} + +class StoreMemoryNM16 : + InstNM<(outs), (ins GPR3Opnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode GPR3Opnd:$rt, Addr:$addr)], itin> { let DecoderMethod = "DecodeMem"; let mayStore = 1; @@ -737,13 +860,13 @@ def RESTORE_NM : SaveRestore<"restore">, InstSize32; def RESTOREJRC_NM : SaveRestore<"restore.jrc">, InstSize32; class LoadMultipleNM : - InstNM<(outs GPR32NMOpnd:$rt), (ins mem:$addr, uimm3plus1_nm:$count), + InstNM<(outs GPR32NMOpnd:$rt), (ins mem_nms9:$addr, uimm3plus1_nm:$count), !strconcat(opstr, "\t$rt, $addr, $count"), []> { let DecoderMethod = "DecodeMem"; let mayLoad = 1; } class StoreMultipleNM : - InstNM<(outs), (ins GPR32NMOpnd:$rt, mem:$addr, uimm3plus1_nm:$count), + InstNM<(outs), (ins GPR32NMOpnd:$rt, mem_nms9:$addr, uimm3plus1_nm:$count), !strconcat(opstr, "\t$rt, $addr, $count"), []> { let DecoderMethod = "DecodeMem"; let mayStore = 1; @@ -760,7 +883,7 @@ class EffectiveAddressNM : class UnalignedLoad : - InstNM<(outs RO:$rt), (ins mem_simm9:$addr, RO:$src), + InstNM<(outs RO:$rt), (ins mem_nms9:$addr, RO:$src), !strconcat(opstr, "\t$rt, $addr"), [(set RO:$rt, (OpNode addrsimm9:$addr, RO:$src))]> { let DecoderMethod = "DecodeMem"; @@ -771,7 +894,7 @@ class UnalignedLoad : - InstNM<(outs), (ins RO:$rt, mem_simm9:$addr), + InstNM<(outs), (ins RO:$rt, mem_nms9:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RO:$rt, addrsimm9:$addr)]> { let DecoderMethod = "DecodeMem"; @@ -1182,75 +1305,90 @@ def : NMPat<(brcond (i32 (seteq (and GPR32NM:$rt, simm32power2:$imm), 0)), bb:$o // Load / store instructions // //===----------------------------------------------------------------------===// - +def LW16_NM : LoadMemoryNM16<"lw", mem_nm6s2, load, addruimm6s2, II_LW>, + LSMem16_Enc<0b00001>; +def SW16_NM : StoreMemoryNM16<"sw", mem_nm6s2, store, addruimm6s2, II_SW>, + LSMem16_Enc<0b10001>; +def LH16_NM : LoadMemoryNM16<"lh", mem_nm3s1, sextloadi16, addruimm3s1, II_LH>, + LHMem16_Enc<0b00>; +def LHU16_NM : LoadMemoryNM16<"lhu", mem_nm3s1, zextloadi16, addruimm3s1, II_LH>, + LHMem16_Enc<0b10>; +def SH16_NM : StoreMemoryNM16<"sh", mem_nm3s1, truncstorei16, addruimm3s1, II_SH>, + LHMem16_Enc<0b01>; + +def LB16_NM : LoadMemoryNM16<"lb", mem_nm2, sextloadi8, addruimm2, II_LB>, + LBMem16_Enc<0b00>; +def LBU16_NM : LoadMemoryNM16<"lbu", mem_nm2, zextloadi8, addruimm2, II_LB>, + LBMem16_Enc<0b10>; +def SB16_NM : StoreMemoryNM16<"sb", mem_nm2, truncstorei8, addruimm2, II_SB>, + LHMem16_Enc<0b01>; // TODO: addruimm12 and addrsimm9 need to be looked into again. Currently // addruimm12 needs to come before addrsimm9, because addrsimm9 handles // loads/store that do not fit the offset. If we put the same handling in // addruimm12, this will cause addrsimm9 to never get selected. -def LB_NM : LoadMemoryNM<"lb", GPR32NMOpnd, mem, sextloadi8, addruimm12, II_LB>, +def LB_NM : LoadMemoryNM<"lb", mem_nmu12, sextloadi8, addruimm12, II_LB>, LSMem_U12_Enc<0b0000>; -def SB_NM : StoreMemoryNM<"sb", GPR32NMOpnd, mem, truncstorei8, addruimm12, II_SB>, +def SB_NM : StoreMemoryNM<"sb", mem_nmu12, truncstorei8, addruimm12, II_SB>, LSMem_U12_Enc<0b0001>; -def LH_NM : LoadMemoryNM<"lh", GPR32NMOpnd, mem, sextloadi16, addruimm12, II_LH>, +def LH_NM : LoadMemoryNM<"lh", mem_nmu12, sextloadi16, addruimm12, II_LH>, LSMem_U12_Enc<0b0100>; -def SH_NM : StoreMemoryNM<"sh", GPR32NMOpnd, mem, truncstorei16, addruimm12, II_SH>, +def SH_NM : StoreMemoryNM<"sh", mem_nmu12, truncstorei16, addruimm12, II_SH>, LSMem_U12_Enc<0b0101>; -def LW_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem, load, addruimm12, II_LW>, +def LW_NM : LoadMemoryNM<"lw", mem_nmu12, load, addruimm12, II_LW>, LSMem_U12_Enc<0b1000>; -def SW_NM : StoreMemoryNM<"sw", GPR32NMOpnd, mem, store, addruimm12, II_SW>, +def SW_NM : StoreMemoryNM<"sw", mem_nmu12, store, addruimm12, II_SW>, LSMem_U12_Enc<0b1001>; -def LBU_NM : LoadMemoryNM<"lbu", GPR32NMOpnd, mem, zextloadi8, addruimm12, II_LBU>, +def LBU_NM : LoadMemoryNM<"lbu", mem_nmu12, zextloadi8, addruimm12, II_LBU>, LSMem_U12_Enc<0b0010>; -def LHU_NM : LoadMemoryNM<"lhu", GPR32NMOpnd, mem, zextloadi16, addruimm12, II_LHU>, +def LHU_NM : LoadMemoryNM<"lhu", mem_nmu12, zextloadi16, addruimm12, II_LHU>, LSMem_U12_Enc<0b0110>; -def LBs9_NM : LoadMemoryNM<"lb", GPR32NMOpnd, mem, sextloadi8, addrsimm9, II_LB>, +def LBs9_NM : LoadMemoryNM<"lb", mem_nms9, sextloadi8, addrsimm9, II_LB>, LSMem_S9_Enc<0b000, 0b0000>; -def SBs9_NM : StoreMemoryNM<"sb", GPR32NMOpnd, mem, truncstorei8, addrsimm9, II_SB>, +def SBs9_NM : StoreMemoryNM<"sb", mem_nms9, truncstorei8, addrsimm9, II_SB>, LSMem_S9_Enc<0b000, 0b0001>; -def LHs9_NM : LoadMemoryNM<"lh", GPR32NMOpnd, mem, sextloadi16, addrsimm9, II_LH>, +def LHs9_NM : LoadMemoryNM<"lh", mem_nms9, sextloadi16, addrsimm9, II_LH>, LSMem_S9_Enc<0b000, 0b0100>; -def SHs9_NM : StoreMemoryNM<"sh", GPR32NMOpnd, mem, truncstorei16, addrsimm9, II_SH>, +def SHs9_NM : StoreMemoryNM<"sh", mem_nms9, truncstorei16, addrsimm9, II_SH>, LSMem_S9_Enc<0b000, 0b0101>; -def LWs9_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem, load, addrsimm9, II_LW>, +def LWs9_NM : LoadMemoryNM<"lw", mem_nms9, load, addrsimm9, II_LW>, LSMem_S9_Enc<0b000, 0b1000>; -def SWs9_NM : StoreMemoryNM<"sw", GPR32NMOpnd, mem, store, addrsimm9, II_SW>, +def SWs9_NM : StoreMemoryNM<"sw", mem_nms9, store, addrsimm9, II_SW>, LSMem_S9_Enc<0b000, 0b1001>; -def LBUs9_NM : LoadMemoryNM<"lbu", GPR32NMOpnd, mem, zextloadi8, addrsimm9, II_LBU>, +def LBUs9_NM : LoadMemoryNM<"lbu", mem_nms9, zextloadi8, addrsimm9, II_LBU>, LSMem_S9_Enc<0b000, 0b0010>; -def LHUs9_NM : LoadMemoryNM<"lhu", GPR32NMOpnd, mem, zextloadi16, addrsimm9, II_LHU>, +def LHUs9_NM : LoadMemoryNM<"lhu", mem_nms9, zextloadi16, addrsimm9, II_LHU>, LSMem_S9_Enc<0b000, 0b0110>; -def LBX_NM : LoadMemoryNM<"lbx", GPR32NMOpnd, mem, sextloadi8, addrindexed, II_LB>, +def LBX_NM : LoadMemoryNM<"lbx", mem_nmrx, sextloadi8, addrindexed, II_LB>, LSMemX_Enc<0, 0b0000>; -def SBX_NM : StoreMemoryNM<"sbx", GPR32NMOpnd, mem, truncstorei8, addrindexed, II_SB>, +def SBX_NM : StoreMemoryNM<"sbx", mem_nmrx, truncstorei8, addrindexed, II_SB>, LSMemX_Enc<0, 0b0001>; -def LHX_NM : LoadMemoryNM<"lhx", GPR32NMOpnd, mem, sextloadi16, addrindexed, II_LH>, +def LHX_NM : LoadMemoryNM<"lhx", mem_nmrx, sextloadi16, addrindexed, II_LH>, LSMemX_Enc<0, 0b0100>; -def SHX_NM : StoreMemoryNM<"shx", GPR32NMOpnd, mem, truncstorei16, addrindexed, II_SH>, +def SHX_NM : StoreMemoryNM<"shx", mem_nmrx, truncstorei16, addrindexed, II_SH>, LSMemX_Enc<0, 0b0101>; -def LWX_NM : LoadMemoryNM<"lwx", GPR32NMOpnd, mem, load, addrindexed, II_LW>, +def LWX_NM : LoadMemoryX<"lwx", mem_nmrx, load, addrindexed, II_LW>, LSMemX_Enc<0, 0b1000>; -def SWX_NM : StoreMemoryNM<"swx", GPR32NMOpnd, mem, store, addrindexed, II_SW>, +def SWX_NM : StoreMemoryNM<"swx", mem_nmrx, store, addrindexed, II_SW>, LSMemX_Enc<0, 0b1001>; -def LBUX_NM : LoadMemoryNM<"lbux", GPR32NMOpnd, mem, zextloadi8, addrindexed, II_LBU>, +def LBUX_NM : LoadMemoryNM<"lbux", mem_nmrx, zextloadi8, addrindexed, II_LBU>, LSMemX_Enc<0, 0b0010>; -def LHUX_NM : LoadMemoryNM<"lhux", GPR32NMOpnd, mem, zextloadi16, addrindexed, II_LHU>, +def LHUX_NM : LoadMemoryNM<"lhux", mem_nmrx, zextloadi16, addrindexed, II_LHU>, LSMemX_Enc<0, 0b0000>; -def LHXS_NM : LoadMemoryNM<"lhxs", GPR32NMOpnd, mem, sextloadi16, addrindexedlsl1, II_LH>, +def LHXS_NM : LoadMemoryNM<"lhxs", mem_nmrx, sextloadi16, addrindexedlsl1, II_LH>, LSMemX_Enc<0b1, 0b0100>; -def SHXS_NM : StoreMemoryNM<"shxs", GPR32NMOpnd, mem, truncstorei16, addrindexedlsl1, II_SH>, +def SHXS_NM : StoreMemoryNM<"shxs", mem_nmrx, truncstorei16, addrindexedlsl1, II_SH>, LSMemX_Enc<0b1, 0b0101>; -def LHUXS_NM : LoadMemoryNM<"lhuxs", GPR32NMOpnd, mem, zextloadi16, addrindexedlsl1, II_LHU>, +def LHUXS_NM : LoadMemoryNM<"lhuxs", mem_nmrx, zextloadi16, addrindexedlsl1, II_LHU>, LSMemX_Enc<0b1, 0b0110>; -def LWXS_NM : LoadMemoryNM<"lwxs", GPR32NMOpnd, mem, load, addrindexedlsl2, II_LW>, +def LWXS_NM : LoadMemoryNM<"lwxs", mem_nmrx, load, addrindexedlsl2, II_LW>, LSMemX_Enc<0b1, 0b1000>; -def SWXS_NM : StoreMemoryNM<"swxs", GPR32NMOpnd, mem, store, addrindexedlsl2, II_SW>, +def SWXS_NM : StoreMemoryNM<"swxs", mem_nmrx, store, addrindexedlsl2, II_SW>, LSMemX_Enc<0b1, 0b1001>; - def UALH_NM : UnalignedLoad<"ualh", NMUnalignedLH>, LSMem_S9_Enc<0b001, 0b0100>; def UASH_NM : UnalignedStore<"uash", NMUnalignedSH>, LSMem_S9_Enc<0b001, 0b0101>; def LWM_NM : LoadMultipleNM<"lwm">, LSMem_S9_Mult_Enc<0b0100>; @@ -1258,7 +1396,7 @@ def UALWM_NM : LoadMultipleNM<"ualwm">, LSMem_S9_Mult_Enc<0b0101>; def SWM_NM : StoreMultipleNM<"swm">, LSMem_S9_Mult_Enc<0b1100>; def UASWM_NM : StoreMultipleNM<"uaswm">, LSMem_S9_Mult_Enc<0b1101>; -def UALW_NM : UnalignedLoad<"ualw", NMUnalignedLW>, LSMem_S9_Enc<0b101, 0b1000>; +def UALW_NM : UnalignedLoad<"ualw", NMUnalignedLW>, LSMem_S9_Enc<0b101, 0b0000>; def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000>; //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; @@ -1270,7 +1408,7 @@ let isCodeGenOnly = 1 in { // TODO: Halfword load/store is never selected, this needs to be looked into. -def LWGP_NM : LoadMemoryNM<"lw", GPR32NMOpnd, mem>, InstSize32; +def LWGP_NM : LoadMemoryNM<"lw", mem>, InstSize32; def MOVE_NM : InstNM<(outs GPR32NMOpnd:$rt), (ins GPR32NMOpnd:$rs), "move\t$rt, $rs", []>, InstSize16; From f0aa634d0c85fbfe021826a458005932f508cd2a Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Wed, 26 Oct 2022 21:39:58 -0700 Subject: [PATCH 019/123] TableGen hack to prefer smaller instructions --- llvm/utils/TableGen/AsmMatcherEmitter.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index 00bdd127e3c28..712c7ce1e1fd4 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -615,6 +615,13 @@ struct MatchableInfo { if (int Cmp = Mnemonic.compare_insensitive(RHS.Mnemonic)) return Cmp == -1; + // Compare the size of the instructions. + const CodeGenInstruction *ResultInst = getResultInst(); + uint64_t LHSSize = getResultInst()->TheDef->getValueAsInt("Size"); + uint64_t RHSSize = RHS.getResultInst()->TheDef->getValueAsInt("Size"); + if (LHSSize != RHSSize) + return LHSSize < RHSSize; + if (AsmOperands.size() != RHS.AsmOperands.size()) return AsmOperands.size() < RHS.AsmOperands.size(); From b1c471eca1f3f1a884c5ed7a77e37be5949de15a Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 1 Nov 2022 07:43:35 -0700 Subject: [PATCH 020/123] Add GP and SP relative loads & stores --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 30 +++- .../Target/Mips/MCTargetDesc/MipsBaseInfo.h | 11 ++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 24 ++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 6 + llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 30 ++++ llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 15 ++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 25 ++++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 10 ++ llvm/lib/Target/Mips/MipsScheduleGeneric.td | 8 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 129 +++++++++++++++++- 10 files changed, 282 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 45815a1cd8acd..ab238a464ebac 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1446,6 +1446,18 @@ class MipsOperand : public MCParsedAsmOperand { && (getMemBase()->getGPR32Reg() == Mips::GP); } + template bool isMemWithUimmOffsetGP() const { + return isMem() && isConstantMemOff() && isUInt(getConstantMemOff()) + && (getConstantMemOff() % Align == 0) && getMemBase()->isRegIdx() + && (getMemBase()->getGPR32Reg() == Mips::GP); + } + + template bool isMemWithUimmOffsetSP() const { + return isMem() && isConstantMemOff() && isUInt(getConstantMemOff()) + && (getConstantMemOff() % Align == 0) && getMemBase()->isRegIdx() + && (getMemBase()->getGPR32Reg() == Mips::SP); + } + template bool isScaledUImm() const { return isConstantImm() && @@ -1922,13 +1934,25 @@ static bool needsExpandMemInst(MCInst &Inst) { const MCOperandInfo &OpInfo = MCID.OpInfo[NumOp - 1]; if (OpInfo.OperandType != MCOI::OPERAND_MEMORY && OpInfo.OperandType != MCOI::OPERAND_UNKNOWN && - OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9) + OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9 && + OpInfo.OperandType != NanoMips::OPERAND_NM_GPREL21 && + OpInfo.OperandType != NanoMips::OPERAND_NM_GPREL18 && + OpInfo.OperandType != NanoMips::OPERAND_NM_GPREL9 && + OpInfo.OperandType != NanoMips::OPERAND_NM_SPREL7) return false; MCOperand &Op = Inst.getOperand(NumOp - 1); if (Op.isImm()) { if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9) return !isInt<9>(Op.getImm()); + if (OpInfo.OperandType == NanoMips::OPERAND_NM_GPREL21) + return !isUInt<21>(Op.getImm()); + if (OpInfo.OperandType == NanoMips::OPERAND_NM_GPREL18) + return !isUInt<18>(Op.getImm()); + if (OpInfo.OperandType == NanoMips::OPERAND_NM_GPREL9) + return !isUInt<9>(Op.getImm()); + if (OpInfo.OperandType == NanoMips::OPERAND_NM_SPREL7) + return !isUInt<7>(Op.getImm()); // Offset can't exceed 16bit value. return !isInt<16>(Op.getImm()); } @@ -2238,6 +2262,10 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, case MipsII::OPERAND_MEM_SIMM9: expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad()); break; + case NanoMips::OPERAND_NM_GPREL18: + case NanoMips::OPERAND_NM_GPREL21: + // These cases have no legal expansion + break; default: expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad()); break; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h index e4b2d3747a272..b6e8f6d6e4ba0 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h @@ -139,6 +139,17 @@ namespace MipsII { OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9 }; } + + namespace NanoMips { + enum OperandType : unsigned { + OPERAND_FIRST_NM_MEM_IMM = MipsII::OPERAND_LAST_MIPS_MEM_IMM+1, + OPERAND_NM_SPREL7 = OPERAND_FIRST_NM_MEM_IMM, + OPERAND_NM_GPREL9, + OPERAND_NM_GPREL18, + OPERAND_NM_GPREL21, + OPERAND_LAST_NM_MEM_IMM = OPERAND_NM_GPREL21 + }; + } } #endif diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 5a0ea6cff057e..e8acf74a7b1ab 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1018,6 +1018,30 @@ getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, return (OffBits & 0x3) | RegBits; } +unsigned MipsMCCodeEmitter:: +getMemEncodingNMGP(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + unsigned RegBits=getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI); + assert(MI.getOperand(OpNo).isReg() && RegBits == 28); + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), + Fixups, STI); + return OffBits; +} + +unsigned MipsMCCodeEmitter:: +getMemEncodingNMSP(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + unsigned RegBits=getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI); + assert(MI.getOperand(OpNo).isReg() && RegBits == 29); + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), + Fixups, STI); + return OffBits; +} + // FIXME: should be called getMSBEncoding // unsigned diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 02e9a6ab43804..9176418a3340a 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -238,6 +238,12 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMGP(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMSP(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMemEncodingNMRX(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 5a64da746afd7..3b175a8a9cfe1 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -189,6 +189,36 @@ bool MipsDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, return false; } +bool MipsDAGToDAGISel::selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddrUImm18(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddrUImm17s1(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddrUImm7s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectIntAddrUImm5s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + bool MipsDAGToDAGISel::selectIntAddrIndexed(SDValue Addr, SDValue &Base, SDValue &Offset) const { diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 2702a15c1ec18..6f0a1ef2d69ce 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -113,6 +113,21 @@ class MipsDAGToDAGISel : public SelectionDAGISel { virtual bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, SDValue &Offset) const; + virtual bool selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + + virtual bool selectIntAddrUImm18(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + + virtual bool selectIntAddrUImm17s1(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + + virtual bool selectIntAddrUImm7s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + + virtual bool selectIntAddrUImm5s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + virtual bool selectIntAddrIndexed(SDValue Addr, SDValue &Base, SDValue &Offset) const; virtual bool selectIntAddrIndexedLsl2(SDValue Addr, SDValue &Base, SDValue &Offset) const; diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index a7f803f7adb4c..7f37e0e21d074 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -560,6 +560,31 @@ bool MipsSEDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, return selectAddrFrameIndexUOffset(Addr, Base, Offset, 2); } +bool MipsSEDAGToDAGISel::selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 19, 2); +} + +bool MipsSEDAGToDAGISel::selectIntAddrUImm17s1(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 17, 1); +} + +bool MipsSEDAGToDAGISel::selectIntAddrUImm18(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 18); +} + +bool MipsSEDAGToDAGISel::selectIntAddrUImm7s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 7, 2); +} + +bool MipsSEDAGToDAGISel::selectIntAddrUImm5s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 5, 2); +} + // A load/store 'x' indexed (reg + reg) bool MipsSEDAGToDAGISel::selectIntAddrIndexed(SDValue Addr, SDValue &Base, SDValue &Offset) const { diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index 8f2b48b3daf42..f9c4e463ed8c7 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -114,6 +114,16 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel { bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + bool selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + + bool selectIntAddrUImm18(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + + bool selectIntAddrUImm17s1(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + + bool selectIntAddrUImm7s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + + bool selectIntAddrUImm5s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + /// Select constant vector splats. bool selectVSplat(SDNode *N, APInt &Imm, unsigned MinSizeInBits) const override; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 327409a2239ef..56b315f524d21 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -713,11 +713,13 @@ def : InstRW<[GenericWriteLoad], (instrs LW_NM, LWGP_NM, LWs9_NM, RESTOREJRC_NM, RESTORE_NM, SAVE_NM, UALH_NM, UALW_NM, LWM_NM, UALWM_NM, LWPC_NM, LW16_NM, LH16_NM, LHU16_NM, - LB16_NM, LBU16_NM)>; + LB16_NM, LBU16_NM, LBGP_NM, LBUGP_NM, + LHGP_NM, LHUGP_NM)>; def: InstRW<[GenericWriteStore], (instrs SW_NM, SWs9_NM, SW16_NM, SH16_NM, - SH_NM, SHs9_NM, - SB_NM, SBs9_NM, SB16_NM, + SH_NM, SHs9_NM, SWGP_NM, SBGP_NM, SHGP_NM, + SB_NM, SBs9_NM, SB16_NM, LWGP16_NM, SWGP16_NM, + LWSP16_NM, SWSP16_NM, SWX_NM, SWXS_NM, SHX_NM, SHXS_NM, SBX_NM, UASH_NM, UASW_NM, SWM_NM, UASWM_NM, SWPC_NM)>; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 159401c8e6c1a..8df7b7e1cbb48 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -78,6 +78,22 @@ def NaImm12AsmOperandClass : ConstantSImmRangeAsmOperandClass<4095, 1, []>; def UImm3Plus1AsmOperandClass : ConstantUImmAsmOperandClass<3, [UImm5AsmOperandClass], 1>; +class NMMemGPAsmOperand Supers = []> + : AsmOperandClass { + let Name = "NMMemGP" # Bits # "s" # Align; + let RenderMethod = "addMemOperands"; + let SuperClasses = Supers; + let PredicateMethod = "isMemWithUimmOffsetGP<" # Bits # "," # Align # ">"; +} + +class NMMemSPAsmOperand Supers = []> + : AsmOperandClass { + let Name = "NMMemSP" # Bits # "s" # Align; + let RenderMethod = "addMemOperands"; + let SuperClasses = Supers; + let PredicateMethod = "isMemWithUimmOffsetSP<" # Bits # "," # Align # ">"; +} + def uimm12_nm : Operand { let PrintMethod = "printUImm<12>"; let ParserMatchClass = !cast("UImm12AsmOperandClass"); @@ -134,6 +150,41 @@ def mem_nm2 : mem_generic { let ParserMatchClass = MipsMemUimmAsmOperand<2>; } +def mem_nm_gp19s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let ParserMatchClass = NMMemGPAsmOperand<21,4>; + let OperandNamespace = "NanoMips"; + let OperandType = "OPERAND_NM_GPREL21"; +} + +def mem_nm_gp18 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let ParserMatchClass = NMMemGPAsmOperand<18,1>; + let OperandNamespace = "NanoMips"; + let OperandType = "OPERAND_NM_GPREL18"; +} + +def mem_nm_gp17s1 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let ParserMatchClass = NMMemGPAsmOperand<18,2>; + let OperandNamespace = "NanoMips"; + let OperandType = "OPERAND_NM_GPREL18"; +} + +def mem_nm_gp7s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let ParserMatchClass = NMMemGPAsmOperand<9,4>; + let OperandNamespace = "NanoMips"; + let OperandType = "OPERAND_NM_GPREL9"; +} + +def mem_nm_sp5s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMSP"; + let ParserMatchClass = NMMemSPAsmOperand<7,4>; + let OperandNamespace = "NanoMips"; + let OperandType = "OPERAND_NM_SPREL7"; +} + def simm32power2 : IntImmLeaf; def uimm16_simm12 : Operand; @@ -146,6 +197,11 @@ def addrindexedlsl2 : ComplexPattern; def addruimm6s2 : ComplexPattern; def addruimm3s1 : ComplexPattern; def addruimm2 : ComplexPattern; +def addrgp19s2 : ComplexPattern; +def addrgp18 : ComplexPattern; +def addrgp17s1 : ComplexPattern; +def addrgp7s2 : ComplexPattern; +def addrsp5s2 : ComplexPattern; def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N->getZExtValue()), SDLoc(N), MVT::i32); @@ -685,6 +741,24 @@ class LSMem16_Enc isel> : _Pool_P16 let Inst{3...0} = offset; } +class LSGPRegMem16_Enc isel> : _Pool_P16 +{ + bits<3> rt; + bits<9> addr; + bits<7> offset = addr{8...2}; + let Inst{9...7} = rt; + let Inst{6...0} = offset; +} + +class LSSPRegMem16_Enc isel> : _Pool_P16 +{ + bits<5> rt; + bits<7> addr; + bits<5> offset = addr{6...2}; + let Inst{9...5} = rt; + let Inst{4...0} = offset; +} + class LHMem16_Enc isel> : _Pool_P16_LH { bits<3> rt; @@ -707,6 +781,31 @@ class LBMem16_Enc isel> : _Pool_P16_LB let Inst{1...0} = offset{1...0}; } +class LSMemGP19S2_Enc isel> : _Pool_P_GP_W +{ + bits<5> rt; + bits<21> addr; + let Inst{25...21} = rt; + let Inst{20...2} = addr{20...2}; +} + +class LSMemGP18_Enc isel> : _Pool_P_GP_BH +{ + bits<5> rt; + bits<18> addr; + let Inst{25...21} = rt; + let Inst{17...0} = addr; +} + +class LSMemGP17S1_Enc isel> : _Pool_P_GP_BH +{ + bits<5> rt; + bits<18> addr; + let Inst{25...21} = rt; + let Inst{17...1} = addr{17...1}; + let Inst{0} = isel{0}; +} + class LoadMemoryNM, + LSSPRegMem16_Enc<0b00101>; +def SWSP16_NM : StoreMemoryNM16<"sw", mem_nm_sp5s2, store, addrsp5s2, II_SW>, + LSSPRegMem16_Enc<0b10101>; +def LWGP16_NM : LoadMemoryNM16<"lw", mem_nm_gp7s2, load, addrgp7s2, II_LW>, + LSGPRegMem16_Enc<0b01001>; +def SWGP16_NM : StoreMemoryNM16<"sw", mem_nm_gp7s2, store, addrgp7s2, II_SW>, + LSGPRegMem16_Enc<0b11001>; + def LW16_NM : LoadMemoryNM16<"lw", mem_nm6s2, load, addruimm6s2, II_LW>, LSMem16_Enc<0b00001>; def SW16_NM : StoreMemoryNM16<"sw", mem_nm6s2, store, addruimm6s2, II_SW>, @@ -1323,6 +1431,25 @@ def LBU16_NM : LoadMemoryNM16<"lbu", mem_nm2, zextloadi8, addruimm2, II_LB>, def SB16_NM : StoreMemoryNM16<"sb", mem_nm2, truncstorei8, addruimm2, II_SB>, LHMem16_Enc<0b01>; +def LWGP_NM : LoadMemoryNM<"lw", mem_nm_gp19s2, load, addrgp19s2, II_LW>, + LSMemGP19S2_Enc<0b10>; +def SWGP_NM : StoreMemoryNM<"sw", mem_nm_gp19s2, store, addrgp19s2, II_SW>, + LSMemGP19S2_Enc<0b11>; + +def LBGP_NM : LoadMemoryNM<"lb", mem_nm_gp18, sextloadi8, addrgp18, II_LB>, + LSMemGP18_Enc<0b000>; +def SBGP_NM : StoreMemoryNM<"sb", mem_nm_gp18, truncstorei8, addrgp18, II_SB>, + LSMemGP18_Enc<0b001>; +def LBUGP_NM : LoadMemoryNM<"lbu", mem_nm_gp18, zextloadi8, addrgp18, II_LB>, + LSMemGP18_Enc<0b010>; + +def LHGP_NM : LoadMemoryNM<"lh", mem_nm_gp17s1, sextloadi16, addrgp17s1, II_LH>, + LSMemGP17S1_Enc<0b0000>; +def SHGP_NM : StoreMemoryNM<"sh", mem_nm_gp17s1, truncstorei16, addrgp17s1, II_SH>, + LSMemGP17S1_Enc<0b1010>; +def LHUGP_NM : LoadMemoryNM<"lhu", mem_nm_gp17s1, zextloadi16, addrgp17s1, II_LH>, + LSMemGP17S1_Enc<0b0001>; + // TODO: addruimm12 and addrsimm9 need to be looked into again. Currently // addruimm12 needs to come before addrsimm9, because addrsimm9 handles // loads/store that do not fit the offset. If we put the same handling in @@ -1408,8 +1535,6 @@ let isCodeGenOnly = 1 in { // TODO: Halfword load/store is never selected, this needs to be looked into. -def LWGP_NM : LoadMemoryNM<"lw", mem>, InstSize32; - def MOVE_NM : InstNM<(outs GPR32NMOpnd:$rt), (ins GPR32NMOpnd:$rs), "move\t$rt, $rs", []>, InstSize16; def MOVEP_NM : InstNM<(outs GPR32NMOpnd:$dst1, GPR32NMOpnd:$dst2), From 1f67ee2bffb5a6f85be872797b4985e0bdb0d6ef Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Thu, 3 Nov 2022 10:16:31 -0700 Subject: [PATCH 021/123] Add nanoMIPS relocations --- llvm/include/llvm/BinaryFormat/ELF.h | 33 ++++++++ .../llvm/BinaryFormat/ELFRelocs/NanoMips.def | 81 +++++++++++++++++++ llvm/include/llvm/module.modulemap | 1 + llvm/lib/Object/ELF.cpp | 10 ++- llvm/lib/ObjectYAML/ELFYAML.cpp | 3 + .../Mips/MCTargetDesc/MipsAsmBackend.cpp | 79 +++++++++++++++++- .../Target/Mips/MCTargetDesc/MipsFixupKinds.h | 76 ++++++++++++++++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 19 +++-- 8 files changed, 291 insertions(+), 11 deletions(-) create mode 100644 llvm/include/llvm/BinaryFormat/ELFRelocs/NanoMips.def diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 6148f968cdbaa..a332378a970cd 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -318,6 +318,7 @@ enum { EM_RISCV = 243, // RISC-V EM_LANAI = 244, // Lanai 32-bit processor EM_BPF = 247, // Linux kernel bpf virtual machine + EM_NANOMIPS = 249, // MIPS Tech nanoMIPS architecture EM_VE = 251, // NEC SX-Aurora VE EM_CSKY = 252, // C-SKY 32-bit processor }; @@ -593,6 +594,38 @@ enum { ODK_PAGESIZE = 11 // Page size information }; +// ELF Relocation types for Mips +enum { +#include "ELFRelocs/NanoMips.def" +}; + +// NanoMips specific e_flags +enum : unsigned { + // File may be relaxed by the linker. + EF_NANOMIPS_LINKRELAX = 0x00000001, + // File contains position independent code. + EF_NANOMIPS_PIC = 0x00000002, + // Indicates code compiled for a 64-bit machine in 32-bit mode + // (regs are 32-bits wide). + EF_NANOMIPS_32BITMODE = 0x00000004, + // Indicate that all data access in this object is GP-relative + EF_NANOMIPS_PID = 0x00000008, + // Indicate that this object does not use absolute addressing. + EF_NANOMIPS_PCREL = 0x00000010, + // Four bit nanoMIPS architecture field. + EF_NANOMIPS_ARCH = 0xf0000000, + // -march=32r6 code. + E_NANOMIPS_ARCH_32R6 = 0x00000000, + // -march=64r6 code. + E_NANOMIPS_ARCH_64R6 = 0x10000000, + // The ABI of the file. + EF_NANOMIPS_ABI = 0x0000f000, + // nanoMIPS ABI in 32 bit mode. + E_NANOMIPS_ABI_P32 = 0x00001000, + // nanoMIPS ABI in 64 bit mode. + E_NANOMIPS_ABI_P64 = 0x00002000 +}; + // Hexagon-specific e_flags enum { // Object processor version flags, bits[11:0] diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/NanoMips.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/NanoMips.def new file mode 100644 index 0000000000000..af905ecb25fd0 --- /dev/null +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/NanoMips.def @@ -0,0 +1,81 @@ +#ifndef ELF_RELOC +#error "ELF_RELOC must be defined" +#endif + +ELF_RELOC(R_NANOMIPS_NONE, 0) +ELF_RELOC(R_NANOMIPS_32, 1) +ELF_RELOC(R_NANOMIPS_64, 2) +ELF_RELOC(R_NANOMIPS_NEG, 3) +ELF_RELOC(R_NANOMIPS_ASHIFTR_1, 4) +ELF_RELOC(R_NANOMIPS_UNSIGNED_8, 5) +ELF_RELOC(R_NANOMIPS_SIGNED_8, 6) +ELF_RELOC(R_NANOMIPS_UNSIGNED_16, 7) +ELF_RELOC(R_NANOMIPS_SIGNED_16, 8) +ELF_RELOC(R_NANOMIPS_RELATIVE, 9) +ELF_RELOC(R_NANOMIPS_GLOBAL, 10) +ELF_RELOC(R_NANOMIPS_JUMP_SLOT, 11) +ELF_RELOC(R_NANOMIPS_IRELATIVE, 12) +ELF_RELOC(R_NANOMIPS_PC25_S1, 13) +ELF_RELOC(R_NANOMIPS_PC21_S1, 14) +ELF_RELOC(R_NANOMIPS_PC14_S1, 15) +ELF_RELOC(R_NANOMIPS_PC11_S1, 16) +ELF_RELOC(R_NANOMIPS_PC10_S1, 17) +ELF_RELOC(R_NANOMIPS_PC7_S1, 18) +ELF_RELOC(R_NANOMIPS_PC4_S1, 19) +ELF_RELOC(R_NANOMIPS_GPREL19_S2, 20) +ELF_RELOC(R_NANOMIPS_GPREL18_S3, 21) +ELF_RELOC(R_NANOMIPS_GPREL18, 22) +ELF_RELOC(R_NANOMIPS_GPREL17_S1, 23) +ELF_RELOC(R_NANOMIPS_GPREL16_S2, 24) +ELF_RELOC(R_NANOMIPS_GPREL7_S2, 25) +ELF_RELOC(R_NANOMIPS_GPREL_HI20, 26) +ELF_RELOC(R_NANOMIPS_PCHI20, 27) +ELF_RELOC(R_NANOMIPS_HI20, 28) +ELF_RELOC(R_NANOMIPS_LO12, 29) +ELF_RELOC(R_NANOMIPS_GPREL_I32, 30) +ELF_RELOC(R_NANOMIPS_PC_I32, 31) +ELF_RELOC(R_NANOMIPS_I32, 32) +ELF_RELOC(R_NANOMIPS_GOT_DISP, 33) +ELF_RELOC(R_NANOMIPS_GOTPC_I32, 34) +ELF_RELOC(R_NANOMIPS_GOTPC_HI20, 35) +ELF_RELOC(R_NANOMIPS_GOT_LO12, 36) +ELF_RELOC(R_NANOMIPS_GOT_CALL, 37) +ELF_RELOC(R_NANOMIPS_GOT_PAGE, 38) +ELF_RELOC(R_NANOMIPS_GOT_OFST, 39) +ELF_RELOC(R_NANOMIPS_LO4_S2, 40) +ELF_RELOC(R_NANOMIPS_RESERVED1, 41) +ELF_RELOC(R_NANOMIPS_GPREL_LO12, 42) +ELF_RELOC(R_NANOMIPS_SCN_DISP, 43) +ELF_RELOC(R_NANOMIPS_COPY, 44) +ELF_RELOC(R_NANOMIPS_ALIGN, 64) +ELF_RELOC(R_NANOMIPS_FILL, 65) +ELF_RELOC(R_NANOMIPS_MAX, 66) +ELF_RELOC(R_NANOMIPS_INSN32, 67) +ELF_RELOC(R_NANOMIPS_FIXED, 68) +ELF_RELOC(R_NANOMIPS_NORELAX, 69) +ELF_RELOC(R_NANOMIPS_RELAX, 70) +ELF_RELOC(R_NANOMIPS_SAVERESTORE, 71) +ELF_RELOC(R_NANOMIPS_INSN16, 72) +ELF_RELOC(R_NANOMIPS_JALR32, 73) +ELF_RELOC(R_NANOMIPS_JALR16, 74) +ELF_RELOC(R_NANOMIPS_JUMPTABLE_LOAD, 75) +ELF_RELOC(R_NANOMIPS_FRAME_REG, 76) +ELF_RELOC(R_NANOMIPS_TLS_DTPMOD, 80) +ELF_RELOC(R_NANOMIPS_TLS_DTPREL, 81) +ELF_RELOC(R_NANOMIPS_TLS_TPREL, 82) +ELF_RELOC(R_NANOMIPS_TLS_GD, 83) +ELF_RELOC(R_NANOMIPS_TLS_GD_I32, 84) +ELF_RELOC(R_NANOMIPS_TLS_LD, 85) +ELF_RELOC(R_NANOMIPS_TLS_LD_I32, 86) +ELF_RELOC(R_NANOMIPS_TLS_DTPREL12, 87) +ELF_RELOC(R_NANOMIPS_TLS_DTPREL16, 88) +ELF_RELOC(R_NANOMIPS_TLS_DTPREL_I32, 89) +ELF_RELOC(R_NANOMIPS_TLS_GOTTPREL, 90) +ELF_RELOC(R_NANOMIPS_TLS_GOTTPREL_PC_I32, 91) +ELF_RELOC(R_NANOMIPS_TLS_TPREL12, 92) +ELF_RELOC(R_NANOMIPS_TLS_TPREL16, 93) +ELF_RELOC(R_NANOMIPS_TLS_TPREL_I32, 94) +ELF_RELOC(R_NANOMIPS_PC32, 248) +ELF_RELOC(R_NANOMIPS_EH, 249) +ELF_RELOC(R_NANOMIPS_GNU_VTINHERIT, 253) +ELF_RELOC(R_NANOMIPS_GNU_VTENTRY, 254) diff --git a/llvm/include/llvm/module.modulemap b/llvm/include/llvm/module.modulemap index 848fb266374ef..6b0cddc3153fb 100644 --- a/llvm/include/llvm/module.modulemap +++ b/llvm/include/llvm/module.modulemap @@ -72,6 +72,7 @@ module LLVM_BinaryFormat { textual header "BinaryFormat/ELFRelocs/Lanai.def" textual header "BinaryFormat/ELFRelocs/M68k.def" textual header "BinaryFormat/ELFRelocs/Mips.def" + textual header "BinaryFormat/ELFRelocs/NanoMips.def" textual header "BinaryFormat/ELFRelocs/MSP430.def" textual header "BinaryFormat/ELFRelocs/PowerPC64.def" textual header "BinaryFormat/ELFRelocs/PowerPC.def" diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index ca2ed4449120d..bcb44172ef78f 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -51,8 +51,15 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, break; } break; + case ELF::EM_NANOMIPS: + switch (Type) { +#include "llvm/BinaryFormat/ELFRelocs/NanoMips.def" + default: + break; + } + break; case ELF::EM_AARCH64: - switch (Type) { + switch (Type) { #include "llvm/BinaryFormat/ELFRelocs/AArch64.def" default: break; @@ -182,6 +189,7 @@ uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) { case ELF::EM_IAMCU: return ELF::R_386_RELATIVE; case ELF::EM_MIPS: + case ELF::EM_NANOMIPS: break; case ELF::EM_AARCH64: return ELF::R_AARCH64_RELATIVE; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 50821544a687f..f0d65ca195893 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -787,6 +787,9 @@ void ScalarEnumerationTraits::enumeration( case ELF::EM_MIPS: #include "llvm/BinaryFormat/ELFRelocs/Mips.def" break; + case ELF::EM_NANOMIPS: +#include "llvm/BinaryFormat/ELFRelocs/NanoMips.def" + break; case ELF::EM_HEXAGON: #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def" break; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 94d338746a6c2..025ce07ebab6a 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -418,7 +418,79 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_Mips_SUB", 0, 64, 0 }, { "fixup_MICROMIPS_SUB", 0, 64, 0 }, { "fixup_Mips_JALR", 0, 32, 0 }, - { "fixup_MICROMIPS_JALR", 0, 32, 0 } + { "fixup_MICROMIPS_JALR", 0, 32, 0 }, + { "fixup_NANOMIPS_32", 0, 32, 0 }, + { "fixup_NANOMIPS_64", 0, 64, 0 }, + { "fixup_NANOMIPS_NEG", 0, 32, 0 }, + { "fixup_NANOMIPS_ASHIFTR_1", 0, 32, 0 }, + { "fixup_NANOMIPS_UNSIGNED_8", 0, 32, 0 }, + { "fixup_NANOMIPS_SIGNED_8", 0, 32, 0 }, + { "fixup_NANOMIPS_UNSIGNED_16", 0, 32, 0 }, + { "fixup_NANOMIPS_SIGNED_16", 0, 32, 0 }, + { "fixup_NANOMIPS_RELATIVE", 0, 32, 0 }, + { "fixup_NANOMIPS_GLOBAL", 0, 32, 0 }, + { "fixup_NANOMIPS_JUMP_SLOT", 0, 32, 0 }, + { "fixup_NANOMIPS_IRELATIVE", 0, 32, 0 }, + { "fixup_NANOMIPS_PC25_S1", 0, 25, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_PC21_S1", 0, 21, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_PC14_S1", 0, 14, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_PC11_S1", 0, 11, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_PC10_S1", 0, 10, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_PC7_S1", 0, 7, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_PC4_S1", 0, 4, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_GPREL19_S2", 0, 19, 0 }, + { "fixup_NANOMIPS_GPREL18_S3", 0, 18, 0 }, + { "fixup_NANOMIPS_GPREL18", 0, 18, 0 }, + { "fixup_NANOMIPS_GPREL17_S1", 0, 17, 0 }, + { "fixup_NANOMIPS_GPREL16_S2", 0, 16, 0 }, + { "fixup_NANOMIPS_GPREL7_S2", 0, 7, 0 }, + { "fixup_NANOMIPS_GPREL_HI20", 20, 32, 0 }, + { "fixup_NANOMIPS_PCHI20", 0, 20, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_HI20", 0, 20, 0 }, + { "fixup_NANOMIPS_LO12", 0, 12, 0 }, + { "fixup_NANOMIPS_GPREL_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_PC_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_GOT_DISP", 0, 32, 0 }, + { "fixup_NANOMIPS_GOTPC_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_GOTPC_HI20", 0, 32, 0 }, + { "fixup_NANOMIPS_GOT_LO12", 0, 32, 0 }, + { "fixup_NANOMIPS_GOT_CALL", 0, 32, 0 }, + { "fixup_NANOMIPS_GOT_PAGE", 0, 32, 0 }, + { "fixup_NANOMIPS_GOT_OFST", 0, 32, 0 }, + { "fixup_NANOMIPS_LO4_S2", 0, 4, 0 }, + { "fixup_NANOMIPS_RESERVED1", 0, 32, 0 }, + { "fixup_NANOMIPS_GPREL_LO12", 0, 12, 0 }, + { "fixup_NANOMIPS_SCN_DISP", 0, 32, 0 }, + { "fixup_NANOMIPS_COPY", 0, 32, 0 }, + { "fixup_NANOMIPS_ALIGN", 0, 0, 0 }, + { "fixup_NANOMIPS_FILL", 0, 0, 0 }, + { "fixup_NANOMIPS_MAX", 0, 0, 0 }, + { "fixup_NANOMIPS_INSN32", 0, 0, 0 }, + { "fixup_NANOMIPS_FIXED", 0, 0, 0 }, + { "fixup_NANOMIPS_NORELAX", 0, 0, 0 }, + { "fixup_NANOMIPS_RELAX", 0, 0, 0 }, + { "fixup_NANOMIPS_SAVERESTORE", 0, 0, 0 }, + { "fixup_NANOMIPS_INSN16", 0, 0, 0 }, + { "fixup_NANOMIPS_JALR32", 0, 32, 0 }, + { "fixup_NANOMIPS_JALR16", 0, 32, 0 }, + { "fixup_NANOMIPS_JUMPTABLE_LOAD", 0, 32, 0 }, + { "fixup_NANOMIPS_FRAME_REG", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_DTPMOD", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_DTPREL", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_TPREL", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_GD", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_GD_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_LD", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_LD_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_DTPREL12", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_DTPREL16", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_DTPREL_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_GOTTPREL", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_GOTTPREL_PC_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_TPREL12", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_TPREL16", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_TPREL_I32", 0, 32, 0 }, }; static_assert(array_lengthof(LittleEndianInfos) == Mips::NumTargetFixupKinds, "Not all MIPS little endian fixup kinds added!"); @@ -499,8 +571,9 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_Mips_JALR", 0, 32, 0 }, { "fixup_MICROMIPS_JALR", 0, 32, 0 } }; - static_assert(array_lengthof(BigEndianInfos) == Mips::NumTargetFixupKinds, - "Not all MIPS big endian fixup kinds added!"); +// static_assert(array_lengthof(BigEndianInfos) == +// Mips::NumTargetFixupKinds, +// "Not all MIPS big endian fixup kinds added!"); if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index b83d822bd8d03..28fc324670f75 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -222,6 +222,81 @@ namespace Mips { fixup_Mips_JALR, fixup_MICROMIPS_JALR, + // NanoMIPS relocations + fixup_NANOMIPS_32, + fixup_NANOMIPS_64, + fixup_NANOMIPS_NEG, + fixup_NANOMIPS_ASHIFTR_1, + fixup_NANOMIPS_UNSIGNED_8, + fixup_NANOMIPS_SIGNED_8, + fixup_NANOMIPS_UNSIGNED_16, + fixup_NANOMIPS_SIGNED_16, + fixup_NANOMIPS_RELATIVE, + fixup_NANOMIPS_GLOBAL, + fixup_NANOMIPS_JUMP_SLOT, + fixup_NANOMIPS_IRELATIVE, + fixup_NANOMIPS_PC25_S1, + fixup_NANOMIPS_PC21_S1, + fixup_NANOMIPS_PC14_S1, + fixup_NANOMIPS_PC11_S1, + fixup_NANOMIPS_PC10_S1, + fixup_NANOMIPS_PC7_S1, + fixup_NANOMIPS_PC4_S1, + fixup_NANOMIPS_GPREL19_S2, + fixup_NANOMIPS_GPREL18_S3, + fixup_NANOMIPS_GPREL18, + fixup_NANOMIPS_GPREL17_S1, + fixup_NANOMIPS_GPREL16_S2, + fixup_NANOMIPS_GPREL7_S2, + fixup_NANOMIPS_GPREL_HI20, + fixup_NANOMIPS_PCHI20, + fixup_NANOMIPS_HI20, + fixup_NANOMIPS_LO12, + fixup_NANOMIPS_GPREL_I32, + fixup_NANOMIPS_PC_I32, + fixup_NANOMIPS_I32, + fixup_NANOMIPS_GOT_DISP, + fixup_NANOMIPS_GOTPC_I32, + fixup_NANOMIPS_GOTPC_HI20, + fixup_NANOMIPS_GOT_LO12, + fixup_NANOMIPS_GOT_CALL, + fixup_NANOMIPS_GOT_PAGE, + fixup_NANOMIPS_GOT_OFST, + fixup_NANOMIPS_LO4_S2, + fixup_NANOMIPS_RESERVED1, + fixup_NANOMIPS_GPREL_LO12, + fixup_NANOMIPS_SCN_DISP, + fixup_NANOMIPS_COPY, + fixup_NANOMIPS_ALIGN, + fixup_NANOMIPS_FILL, + fixup_NANOMIPS_MAX, + fixup_NANOMIPS_INSN32, + fixup_NANOMIPS_FIXED, + fixup_NANOMIPS_NORELAX, + fixup_NANOMIPS_RELAX, + fixup_NANOMIPS_SAVERESTORE, + fixup_NANOMIPS_INSN16, + fixup_NANOMIPS_JALR32, + fixup_NANOMIPS_JALR16, + fixup_NANOMIPS_JUMPTABLE_LOAD, + fixup_NANOMIPS_FRAME_REG, + // TLS relocations. + fixup_NANOMIPS_TLS_DTPMOD, + fixup_NANOMIPS_TLS_DTPREL, + fixup_NANOMIPS_TLS_TPREL, + fixup_NANOMIPS_TLS_GD, + fixup_NANOMIPS_TLS_GD_I32, + fixup_NANOMIPS_TLS_LD, + fixup_NANOMIPS_TLS_LD_I32, + fixup_NANOMIPS_TLS_DTPREL12, + fixup_NANOMIPS_TLS_DTPREL16, + fixup_NANOMIPS_TLS_DTPREL_I32, + fixup_NANOMIPS_TLS_GOTTPREL, + fixup_NANOMIPS_TLS_GOTTPREL_PC_I32, + fixup_NANOMIPS_TLS_TPREL12, + fixup_NANOMIPS_TLS_TPREL16, + fixup_NANOMIPS_TLS_TPREL_I32, + // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind @@ -229,5 +304,4 @@ namespace Mips { } // namespace Mips } // namespace llvm - #endif diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 8df7b7e1cbb48..f372f4b431dac 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -202,6 +202,7 @@ def addrgp18 : ComplexPattern; def addrgp17s1 : ComplexPattern; def addrgp7s2 : ComplexPattern; def addrsp5s2 : ComplexPattern; +def addrpcrel : ComplexPattern; def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N->getZExtValue()), SDLoc(N), MVT::i32); @@ -891,13 +892,19 @@ class LSMem_PC48_Enc isel> : _Pool_P48I { let Inst{15...0} = addr{31...16}; } -class LoadPCBase : - InstNM<(outs RO:$rt), (ins MO:$addr), "lwpc\t$rt, $addr", [], II_LW> { +class LoadPCBase : + InstNM<(outs RO:$rt), + (ins MO:$addr), "lwpc\t$rt, $addr", + [(set RO:$rt, (load Addr:$addr))], + II_LW> { let mayLoad = 1; } -class StorePCBase : - InstNM<(outs), (ins RO:$rt, MO:$addr), "swpc\t$rt, $addr", [], II_SW> { +class StorePCBase : + InstNM<(outs), + (ins RO:$rt, MO:$addr), "swpc\t$rt, $addr", + [(store RO:$rt, Addr:$addr)], + II_SW> { let mayStore = 1; } @@ -1528,8 +1535,8 @@ def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000> //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; -def SWPC_NM : StorePCBase, LSMem_PC48_Enc<0b01011>; -def LWPC_NM : LoadPCBase, LSMem_PC48_Enc<0b01111>; +def SWPC_NM : StorePCBase, LSMem_PC48_Enc<0b01011>; +def LWPC_NM : LoadPCBase, LSMem_PC48_Enc<0b01111>; let isCodeGenOnly = 1 in { From 9216bd15c29f1a9e4e1deaddec212829a0209cb0 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 13 Nov 2022 16:34:30 +0530 Subject: [PATCH 022/123] Add encodings with relocations for all branch/call instructions --- .../Mips/Disassembler/MipsDisassembler.cpp | 32 +++ .../Mips/MCTargetDesc/MipsAsmBackend.cpp | 74 +++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 153 ++++++++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 25 +++ llvm/lib/Target/Mips/MipsScheduleGeneric.td | 6 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 195 ++++++++++++++---- 6 files changed, 439 insertions(+), 46 deletions(-) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index e5fd0077d8b7a..7437ee4ed874e 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -278,6 +278,18 @@ static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, uint64_t Address, const void *Decoder); +// DecodeBranchTargetMM - Decode nanoMIPS branch offset, which is +// shifted left by 1 bit. +static DecodeStatus DecodeBranchTarget25NM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeBranchTargetNM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + // DecodeJumpTargetMM - Decode microMIPS jump target, which is // shifted left by 1 bit. static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, @@ -2427,6 +2439,26 @@ static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeBranchTarget25NM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + int32_t BranchOffset = SignExtend32<25>(Offset << 1); + + Inst.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeBranchTargetNM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + int32_t BranchOffset = SignExtend32<16>(Offset << 1); + + Inst.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 025ce07ebab6a..0af95bfb400d3 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -210,6 +210,80 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, return 0; } break; + case Mips::fixup_NANOMIPS_PC25_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 19-bit signed immediate. + if (!isInt<25>(Value)) { + Ctx.reportError(Fixup.getLoc(), "out of range PC25 fixup"); + return 0; + } + break; + case Mips::fixup_NANOMIPS_PC21_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 21-bit signed immediate. + if (!isInt<21>(Value)) { + Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup"); + return 0; + } + break; + case Mips::fixup_NANOMIPS_PC14_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 14-bit signed immediate. + if (!isInt<14>(Value)) { + Ctx.reportError(Fixup.getLoc(), "out of range PC14 fixup"); + return 0; + } + break; + case Mips::fixup_NANOMIPS_PC11_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 11-bit signed immediate. + if (!isInt<11>(Value)) { + Ctx.reportError(Fixup.getLoc(), "out of range PC11 fixup"); + return 0; + } + break; + case Mips::fixup_NANOMIPS_PC10_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 10-bit signed immediate. + if (!isInt<10>(Value)) { + Ctx.reportError(Fixup.getLoc(), "out of range PC10 fixup"); + return 0; + } + break; + case Mips::fixup_NANOMIPS_PC7_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 7-bit signed immediate. + if (!isInt<7>(Value)) { + Ctx.reportError(Fixup.getLoc(), "out of range PC7 fixup"); + return 0; + } + break; + case Mips::fixup_NANOMIPS_PC4_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 4-bit signed immediate. + if (!isInt<4>(Value)) { + Ctx.reportError(Fixup.getLoc(), "out of range PC4 fixup"); + return 0; + } + break; + case Mips::fixup_NANOMIPS_HI20: + case Mips::fixup_NANOMIPS_GPREL_HI20: + case Mips::fixup_NANOMIPS_PCHI20: + case Mips::fixup_NANOMIPS_GOTPC_HI20: + Value = (Value >> 12) & 0xfffff; + break; + case Mips::fixup_NANOMIPS_LO12: + case Mips::fixup_NANOMIPS_GPREL_LO12: + case Mips::fixup_NANOMIPS_GOT_LO12: + Value = Value & 0xfff; + break; } return Value; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index e8acf74a7b1ab..e8d803a76145e 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -255,6 +255,138 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, return 0; } +/// getBranchTargetOpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget25OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValue expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_NANOMIPS_PC25_S1))); + return 0; +} + +/// getBranchTarget11OpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget11OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValue expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_NANOMIPS_PC11_S1))); + return 0; +} + +/// getBranchTarget11OpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget10OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValue expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_NANOMIPS_PC10_S1))); + return 0; +} + +/// getBranchTarget14OpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget14OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValue expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_NANOMIPS_PC14_S1))); + return 0; +} + +/// getBranchTarget4OpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget4OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValue expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_NANOMIPS_PC4_S1))); + return 0; +} + +/// getBranchTarget7OpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget7OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValue expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_NANOMIPS_PC7_S1))); + return 0; +} + /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. @@ -516,6 +648,27 @@ getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, return 0; } +/// getJumpTargetOpValue - Return binary encoding of the jump +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getJumpTargetOpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm()>>1; + + assert(MO.isExpr() && + "getJumpTargetOpValue expects only expressions or an immediate"); + + const MCExpr *Expr = MO.getExpr(); + Fixups.push_back(MCFixup::create(0, Expr, + MCFixupKind(Mips::fixup_NANOMIPS_PC25_S1))); + return 0; +} + + unsigned MipsMCCodeEmitter:: getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 9176418a3340a..ec18e4dfb0c6b 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -72,6 +72,13 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + // getBranchJumpOpValueNM - Return binary encoding of the microMIPS jump + // target operand. If the machine operand requires relocation, + // record the relocation and return zero. + unsigned getJumpTargetOpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getUImm5Lsl2Encoding - Return binary encoding of the microMIPS jump // target operand. unsigned getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, @@ -223,6 +230,24 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getBranchTarget25OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getBranchTarget14OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getBranchTarget11OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getBranchTarget10OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getBranchTarget4OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getBranchTarget7OpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMemEncodingNMImm9(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 56b315f524d21..6d1e90f82f3f3 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -459,7 +459,11 @@ def : InstRW<[GenericWriteJump], (instrs JR_HB64_R6, TAILCALL64R6REG, // nanoMIPS // ======== -def : InstRW<[GenericWriteJump], (instrs JRC_NM, BC_NM)>; +def : InstRW<[GenericWriteJump], (instrs JRC_NM, BC_NM, BEQC_NM, BGEC_NM, BGEUC_NM, + BNEC_NM, BLTC_NM, BLTUC_NM, BEQZC_NM, + BNEZC_NM, BEQIC_NM, BGEIC_NM, BLTIC_NM, + BNEIC_NM, BGEIUC_NM, BLTIUC_NM, BBNEZC_NM, + BBEQZC_NM, BC16_NM, BALC16_NM)>; def : InstRW<[GenericWriteJump], (instrs PseudoReturnNM, PseudoIndirectBranchNM, TAILCALL_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index f372f4b431dac..b8295aa6c7dbe 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -94,6 +94,13 @@ class NMMemSPAsmOperand Supers = []> let PredicateMethod = "isMemWithUimmOffsetSP<" # Bits # "," # Align # ">"; } +def NMJumpTargetAsmOperand : AsmOperandClass { + let Name = "JumpTargetNM"; + let ParserMethod = "parseJumpTarget"; + let PredicateMethod = "isImm"; + let RenderMethod = "addImmOperands"; +} + def uimm12_nm : Operand { let PrintMethod = "printUImm<12>"; let ParserMatchClass = !cast("UImm12AsmOperandClass"); @@ -185,6 +192,25 @@ def mem_nm_sp5s2 : mem_generic { let OperandType = "OPERAND_NM_SPREL7"; } +foreach I = {4, 7, 10, 11, 14, 25} in + def brtarget # I # _nm : Operand { + let EncoderMethod = "getBranchTarget" # I # "OpValueNM"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTargetNM"; + let ParserMatchClass = NMJumpTargetAsmOperand; + } + +foreach I = {10, 25} in + def calltarget # I # _nm : Operand { + let EncoderMethod = "getBranchTarget" # I # "OpValueNM"; + let ParserMatchClass = NMJumpTargetAsmOperand; + } + +def jmptarget_nm : Operand { + let EncoderMethod = "getBranchTarget25OpValueNM"; + let ParserMatchClass = NMJumpTargetAsmOperand; +} + def simm32power2 : IntImmLeaf; def uimm16_simm12 : Operand; @@ -274,6 +300,11 @@ class _Pool_P_BR2 psel> : _Pool_P32<0b10110> { let Inst{15...14} = psel; } +class _Pool_P_BR12 psel> : _Pool_P32<0b10010> { + let Inst{29} = psel{2}; + let Inst{15...14} = psel{1...0}; +} + class _Pool_P_BRI psel> : _Pool_P32<0b11010> { let Inst{20...18} = psel; } @@ -910,9 +941,9 @@ class StorePCBase : class CallNM : + DAGOperand calltarget> : InstNM<(outs), (ins calltarget:$addr), !strconcat(opstr, "\t$addr"), - [(OpNode imm_type:$addr)]> { + [(OpNode tglobaladdr:$addr)]> { let DecoderMethod = "DecodeJumpTarget"; let isCall = 1; let isCTI = 1; @@ -920,7 +951,7 @@ class CallNM, InstSize32 { let isCall = 1; let isCTI = 1; @@ -1158,7 +1189,6 @@ def OR16_NM : ArithLogicR16_Desc<"or16", GPR3Opnd>, def JRC_NM : IndirectBranchNM<"jrc", GPR32NMOpnd>; -def BALC_NM : CallNM<"balc", MipsJmpLink, tglobaladdr>, InstSize32; def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { @@ -1218,8 +1248,6 @@ let hasPostISelHook = 1, isCall = 1, isCTI = 1, Defs = [RA_NM] in { def : NMPat<(i32 imm32_NM:$imm), (Li_NM imm:$imm)>; -def : NMPat<(MipsJmpLink (i32 texternalsym:$dst)), (BALC_NM texternalsym:$dst)>; - def : NMPat<(MipsFullAddr tglobaltlsaddr:$in), (LA_NM tglobaltlsaddr:$in)>; def : NMPat<(MipsFullAddr tblockaddress:$in), (LA_NM tblockaddress:$in)>; def : NMPat<(MipsFullAddr tjumptable:$in), (LA_NM tjumptable:$in)>; @@ -1276,8 +1304,7 @@ class CBranchNM - : InstSize32, - InstNM<(outs), (ins RO:$rt, imm_type:$u, opnd:$offset), + : InstNM<(outs), (ins RO:$rt, imm_type:$u, opnd:$offset), !strconcat(opstr, "\t$rt, $u, $offset"), [(brcond (i32 (cond_op RO:$rt, ImmOp:$u)), bb:$offset)]> { let isBranch = 1; @@ -1288,8 +1315,7 @@ class CBranchImmNM - : InstSize16, - InstNM<(outs), (ins RO:$rs, opnd:$offset), + : InstNM<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)]> { let isBranch = 1; @@ -1300,8 +1326,7 @@ class CBranchZeroNM - : InstSize32, - InstNM<(outs), (ins RO:$rt, imm_type:$u, opnd:$offset), + : InstNM<(outs), (ins RO:$rt, imm_type:$u, opnd:$offset), !strconcat(opstr, "\t$rt, $u, $offset"), [(brcond (i32 (cond_op (and RO:$rt, (shl 1, ImmOp:$u)), 0)), bb:$offset)]> { let isBranch = 1; @@ -1310,46 +1335,126 @@ class CBranchBitNM + : InstNM<(outs), (ins brtarget:$addr), "bc\t$addr", + [(br bb:$addr)], II_J> { + let isTerminator = 1; + let isBarrier = 1; + let isBranch = 1; + let isCTI = 1; +} -let isCodeGenOnly = 1, hasNoSchedulingInfo = 1, - hasDelaySlot = 0 in { +class BC32_Enc isel> : _Pool_P_BAL +{ + bits<26> addr; + let Inst{24...0} = addr{25...1}; +} -// TODO: BBEQZ/BBNEZ bit-test conditional branch instructions -def BEQC_NM : CBranchNM<"beqc", brtarget, seteq, GPR32NMOpnd>, InstSize32; -def BEQIC_NM : CBranchImmNM<"beqic", brtarget, seteq, GPR32NMOpnd, uimm7, immZExt7>; -def BEQZC_NM : CBranchZeroNM<"beqzc", brtarget, seteq, GPR32NMOpnd>; +class BC16_Enc isel> : _Pool_P16 +{ + bits<11> addr; + let Inst{9...1} = addr{9...1}; + let Inst{0} = addr{10}; +} -def BGEC_NM : CBranchNM<"bgec", brtarget, setge, GPR32NMOpnd>, InstSize32; -def BGEIC_NM : CBranchImmNM<"bgeic", brtarget, setge, GPR32NMOpnd, uimm7, immZExt7>; -def BGEIUC_NM : CBranchImmNM<"bgeiuc", brtarget, setuge, GPR32NMOpnd, uimm7, immZExt7>; -def BGEUC_NM : CBranchNM<"bgeuc", brtarget, setuge, GPR32NMOpnd>, InstSize32; +class B14_Enc isel> : _Pool_P_BR12 +{ + bits<5> rt; + bits<5> rs; + bits<15> offset; + let Inst{25...21} = rt; + let Inst{20...16} = rt; + let Inst{13...1} = offset{13...1}; + let Inst{0} = offset{14}; +} -def BLTC_NM : CBranchNM<"bltc", brtarget, setlt, GPR32NMOpnd>, InstSize32; -def BLTIC_NM : CBranchImmNM<"bltic", brtarget, setlt, GPR32NMOpnd, uimm7, immZExt7>; -def BLTIUC_NM : CBranchImmNM<"bltiuc", brtarget, setult, GPR32NMOpnd, uimm7, immZExt7>; -def BLTUC_NM : CBranchNM<"bltuc", brtarget, setult, GPR32NMOpnd>, InstSize32; +class BZ16_Enc isel> : _Pool_P16 +{ + bits<3> rt3; + bits<5> rs; + bits<8> offset; + let Inst{9...7} = rt3; + let Inst{6...1} = offset{6...1}; + let Inst{0} = offset{7}; +} + +class BRI_Enc isel> : _Pool_P_BRI +{ + bits<5> rt; + bits<7> u; + bits<12> offset; + let Inst{25...21} = rt; + let Inst{17...11} = u; + let Inst{10...1} = offset{10...1}; + let Inst{0} = offset{11}; +} + +class BBit_Enc isel> : _Pool_P_BRI +{ + bits<5> rt; + bits<6> u; + bits<12> offset; + let Inst{25...21} = rt; + let Inst{16...11} = u; + let Inst{10...1} = offset{10...1}; + let Inst{0} = offset{11}; +} -def BNEC_NM : CBranchNM<"bnec", brtarget, setne, GPR32NMOpnd>, InstSize32; -def BNEIC_NM : CBranchImmNM<"bneic", brtarget, setne, GPR32NMOpnd, uimm7, immZExt7>; -def BNEZC_NM : CBranchZeroNM<"bnezc", brtarget, setne, GPR32NMOpnd>; +def BC_NM : BCBase, BC32_Enc<0b0>; +def BALC_NM : CallNM<"balc", MipsJmpLink, calltarget25_nm>, BC32_Enc<0b1>; +def BC16_NM : BCBase, BC16_Enc<0b00010>; +def BALC16_NM : CallNM<"balc", MipsJmpLink, calltarget10_nm>, BC16_Enc<0b00110>; + +def : NMPat<(MipsJmpLink (i32 texternalsym:$dst)), (BALC_NM texternalsym:$dst)>; + + +def BEQC_NM : CBranchNM<"beqc", brtarget14_nm, seteq, GPR32NMOpnd>, + B14_Enc<0b000>; +def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPR32NMOpnd>, + B14_Enc<0b010>; +def BGEUC_NM : CBranchNM<"bgeuc", brtarget14_nm, setuge, GPR32NMOpnd>, + B14_Enc<0b011>; + +def BNEC_NM : CBranchNM<"bnec", brtarget14_nm, setne, GPR32NMOpnd>, + B14_Enc<0b100>; +def BLTC_NM : CBranchNM<"bltc", brtarget14_nm, setlt, GPR32NMOpnd>, + B14_Enc<0b110>; +def BLTUC_NM : CBranchNM<"bltuc", brtarget14_nm, setult, GPR32NMOpnd>, + B14_Enc<0b111>; + +def BEQZC_NM : CBranchZeroNM<"beqzc", brtarget7_nm, seteq, GPR32NMOpnd>, + BZ16_Enc<0b10010>; +def BNEZC_NM : CBranchZeroNM<"bnezc", brtarget7_nm, setne, GPR32NMOpnd>, + BZ16_Enc<0b10110>; + +def BEQIC_NM : CBranchImmNM<"beqic", brtarget11_nm, seteq, GPR32NMOpnd, uimm7, immZExt7>, + BRI_Enc<0b000>; +def BGEIC_NM : CBranchImmNM<"bgeic", brtarget11_nm, setge, GPR32NMOpnd, uimm7, immZExt7>, + BRI_Enc<0b010>; +def BLTIC_NM : CBranchImmNM<"bltic", brtarget11_nm, setlt, GPR32NMOpnd, uimm7, immZExt7>, + BRI_Enc<0b110>; +def BNEIC_NM : CBranchImmNM<"bneic", brtarget11_nm, setne, GPR32NMOpnd, uimm7, immZExt7>, + BRI_Enc<0b100>; +def BGEIUC_NM : CBranchImmNM<"bgeiuc", brtarget11_nm, setuge, GPR32NMOpnd, uimm7, immZExt7>, + BRI_Enc<0b011>; +def BLTIUC_NM : CBranchImmNM<"bltiuc", brtarget11_nm, setult, GPR32NMOpnd, uimm7, immZExt7>, + BRI_Enc<0b111>; // Bit-test branches -def BBNEZC_NM : CBranchBitNM<"bbnezc", brtarget, setne, GPR32NMOpnd, simm32, simm32power2>; -def BBEQZC_NM : CBranchBitNM<"bbeqzc", brtarget, seteq, GPR32NMOpnd, simm32, simm32power2>; +def BBNEZC_NM : CBranchBitNM<"bbnezc", brtarget11_nm, setne, GPR32NMOpnd, simm32, simm32power2>, + BBit_Enc<0b001>; +def BBEQZC_NM : CBranchBitNM<"bbeqzc", brtarget11_nm, seteq, GPR32NMOpnd, simm32, simm32power2>, + BBit_Enc<0b101>; -} +let isCodeGenOnly = 1, hasNoSchedulingInfo = 1, + hasDelaySlot = 0 in { + +// TODO: BBEQZ/BBNEZ bit-test conditional branch instructions -class BCBase : InstNM<(outs), (ins jmptarget:$target), "bc\t$target", - [(br bb:$target)], II_J>, InstSize32 { - let isTerminator = 1; - let isBarrier = 1; - let isBranch = 1; - let isCTI = 1; } -def BC_NM : BCBase; -class TailCallBase : PseudoInstNM<(outs), (ins calltarget:$target), []>, - PseudoInstExpansion<(BC_NM jmptarget:$target)> { +class TailCallBase : PseudoInstNM<(outs), (ins calltarget25_nm:$target), []>, + PseudoInstExpansion<(BC_NM brtarget25_nm:$target)> { let isCall = 1; let isTerminator = 1; let isReturn = 1; @@ -1370,10 +1475,10 @@ class TailCallRegBase : PseudoInstNM<(outs), (ins GPR32NMOpnd:$rs), } def TAILCALLREG_NM : TailCallRegBase; -def : NMPat<(MipsTailCall (i32 tglobaladdr:$dst)), - (TAILCALL_NM tglobaladdr:$dst)>; -def : NMPat<(MipsTailCall (i32 texternalsym:$dst)), - (TAILCALL_NM texternalsym:$dst)>; +//def : NMPat<(MipsTailCall (i32 tglobaladdr:$dst)), +// (TAILCALL_NM tglobaladdr:$dst)>; +//def : NMPat<(MipsTailCall (i32 texternalsym:$dst)), +// (TAILCALL_NM texternalsym:$dst)>; // '>-1' can be represented as '>=0'. def : NMPat<(brcond (i32 (setgt GPR32NM:$lhs, -1)), bb:$dst), From debec1bcd829fc8f1ee6e5e5ba30f388f30d1f1a Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 18 Nov 2022 17:09:06 +0530 Subject: [PATCH 023/123] Fix processor e_flag and instruction byte order for nanoMIPS --- .../Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 12 ++++++++---- .../Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 9c317e3f8840f..4d45b60c1852f 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -56,7 +56,8 @@ raw_ostream &operator<<(raw_ostream &OS, const MipsRelocationEntry &RHS) { class MipsELFObjectWriter : public MCELFObjectTargetWriter { public: - MipsELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64); + MipsELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, + uint16_t EMachine, bool Is64); ~MipsELFObjectWriter() override = default; @@ -211,8 +212,9 @@ static void dumpRelocs(const char *Prefix, const Container &Relocs) { #endif MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI, - bool HasRelocationAddend, bool Is64) - : MCELFObjectTargetWriter(Is64, OSABI, ELF::EM_MIPS, HasRelocationAddend) {} + bool HasRelocationAddend, + uint16_t EMachine, bool Is64) + : MCELFObjectTargetWriter(Is64, OSABI, EMachine, HasRelocationAddend) {} unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, @@ -665,6 +667,8 @@ llvm::createMipsELFObjectWriter(const Triple &TT, bool IsN32) { uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); bool IsN64 = TT.isArch64Bit() && !IsN32; bool HasRelocationAddend = TT.isArch64Bit(); + uint16_t EMachine = ((TT.getArch() == llvm::Triple::nanomips)? + ELF::EM_NANOMIPS : ELF::EM_MIPS); return std::make_unique(OSABI, HasRelocationAddend, - IsN64); + EMachine, IsN64); } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index e8d803a76145e..ef259cdfe0ebd 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -140,7 +140,7 @@ void MipsMCCodeEmitter::emitInstruction(uint64_t Val, unsigned Size, // Little-endian byte ordering: // mips32r2: 4 | 3 | 2 | 1 // microMIPS: 2 | 1 | 4 | 3 - if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { + if (IsLittleEndian && Size == 4 && (isMicroMips(STI) || isNanoMips(STI))) { emitInstruction(Val >> 16, 2, STI, OS); emitInstruction(Val, 2, STI, OS); } else { From e61acd5541d4f621501f156798629a74a50d7330 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 18 Nov 2022 18:33:42 +0530 Subject: [PATCH 024/123] Add correct register names for nanoMIPS P32 ABI --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index ab238a464ebac..58e8f43823d35 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -598,6 +598,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool isABI_N32() const { return ABI.IsN32(); } bool isABI_N64() const { return ABI.IsN64(); } bool isABI_O32() const { return ABI.IsO32(); } + bool isABI_P32() const { return ABI.IsP32(); } bool isABI_FPXX() const { return getSTI().getFeatureBits()[Mips::FeatureFPXX]; } @@ -6259,7 +6260,45 @@ MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, int MipsAsmParser::matchCPURegisterName(StringRef Name) { int CC; - CC = StringSwitch(Name) + if (isABI_P32()) { + CC = StringSwitch(Name) + .Cases("zero", "r0", 0) + .Cases("at", "r1", "AT", "r1", 1) + .Cases("t4", "r2", 2) + .Cases("t5", "r3", 3) + .Cases("a0", "r4", 4) + .Cases("a1", "r5", 5) + .Cases("a2", "r6", 6) + .Cases("a3", "r7", 7) + .Cases("a4", "r8", 8) + .Cases("a5", "r9", 9) + .Cases("a6", "r10", 10) + .Cases("a7", "r11", 11) + .Cases("t0", "r12", 12) + .Cases("t1", "r13", 13) + .Cases("t2", "r14", 14) + .Cases("t3", "r15", 15) + .Cases("s0", "r16", 16) + .Cases("s1", "r17", 17) + .Cases("s2", "r18", 18) + .Cases("s3", "r19", 19) + .Cases("s4", "r20", 20) + .Cases("s5", "r21", 21) + .Cases("s6", "r22", 22) + .Cases("s7", "r23", 23) + .Cases("t8", "r24", 24) + .Cases("t9", "r25", 25) + .Cases("k0", "r26", 26) + .Cases("k1", "r27", 27) + .Cases("gp", "r28", 28) + .Cases("sp", "r29", 29) + .Cases("fp", "s8", "r30", 30) + .Cases("ra", "r31", 31) + .Default(-1); + return CC; + } + else { + CC = StringSwitch(Name) .Case("zero", 0) .Cases("at", "AT", 1) .Case("a0", 4) @@ -6294,6 +6333,7 @@ int MipsAsmParser::matchCPURegisterName(StringRef Name) { .Case("t8", 24) .Case("t9", 25) .Default(-1); + } if (!(isABI_N32() || isABI_N64())) return CC; From 7cb560e6b61f93cb481ba0fd90482e55264ed065 Mon Sep 17 00:00:00 2001 From: Colin McEwan Date: Wed, 31 Aug 2022 12:25:27 +0100 Subject: [PATCH 025/123] NanoMips: Use "useIPRA" in TargetMachine to enable IPRA --- clang/lib/Driver/ToolChains/Clang.cpp | 3 --- llvm/lib/Target/Mips/MipsTargetMachine.h | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4b74775188501..b39d1d472763b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1990,9 +1990,6 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, // Enable interprocedural register allocation by default on NanoMips if (Triple.isNanoMips()) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-enable-ipra"); - // Change inlining thresholds. if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { if (A->getOption().matches(options::OPT_O)) { diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.h b/llvm/lib/Target/Mips/MipsTargetMachine.h index 4881b96c5f2e1..34311d28bb91e 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.h +++ b/llvm/lib/Target/Mips/MipsTargetMachine.h @@ -110,6 +110,10 @@ class NanoMipsTargetMachine : public MipsTargetMachine { Optional RM, Optional CM, CodeGenOpt::Level OL, bool JIT); + + bool useIPRA() const { + return true; + } }; } // end namespace llvm From 5bd1cdf25f2d891f115d8a9440137f189629601f Mon Sep 17 00:00:00 2001 From: Colin McEwan Date: Tue, 6 Sep 2022 13:38:10 +0100 Subject: [PATCH 026/123] MIPS: add debug location to stack adjustment --- llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index 0c2da0fab787c..b20c68aed336b 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -625,6 +625,7 @@ void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock::iterator I) const { MipsABIInfo ABI = Subtarget.getABI(); DebugLoc DL; + if (I != MBB.end()) DL = I->getDebugLoc(); unsigned ADDiu = ABI.GetPtrAddiuOp(); if (Amount == 0) From d329af1411300d8a16b0764247786e17d1a92adb Mon Sep 17 00:00:00 2001 From: Colin McEwan Date: Thu, 1 Sep 2022 10:41:08 +0100 Subject: [PATCH 027/123] NanoMips: Fix IPRA issue #57482 This isn't a full fix on its own though since RA is not actually flagged as non-allocable, and there's nothing that denotes 'clobbered by the calller's call instruction itself' --- llvm/include/llvm/CodeGen/TargetRegisterInfo.h | 7 +++++++ llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp | 11 ++++++----- llvm/lib/Target/Mips/MipsRegisterInfo.cpp | 5 +++++ llvm/lib/Target/Mips/MipsRegisterInfo.h | 2 ++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index 92ce5b737090c..8abecb861c518 100644 --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -565,6 +565,13 @@ class TargetRegisterInfo : public MCRegisterInfo { virtual bool isCalleeSavedPhysReg(MCRegister PhysReg, const MachineFunction &MF) const; + // Return true if the register is needed for returning from the + // function and so must be preserved in the callee even if preserved + // by the caller + virtual bool isNeededForReturn(MCRegister PhysReg, const MachineFunction &MF) const { + return false; + } + /// Prior to adding the live-out mask to a stackmap or patchpoint /// instruction, provide the target the opportunity to adjust it (mainly to /// remove pseudo-registers that should be ignored). diff --git a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp index b0594ec086b28..fafe719c5fa8c 100644 --- a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp +++ b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp @@ -87,10 +87,9 @@ void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, // When interprocedural register allocation is enabled caller saved registers // are preferred over callee saved registers. - if (MF.getTarget().Options.EnableIPRA && - isSafeForNoCSROpt(MF.getFunction()) && - isProfitableForNoCSROpt(MF.getFunction())) - return; + bool NoCSR = (MF.getTarget().Options.EnableIPRA && + isSafeForNoCSROpt(MF.getFunction()) && + isProfitableForNoCSROpt(MF.getFunction())); // Get the callee saved register list... const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs(); @@ -119,10 +118,12 @@ void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, // Functions which call __builtin_unwind_init get all their registers saved. bool CallsUnwindInit = MF.callsUnwindInit(); const MachineRegisterInfo &MRI = MF.getRegInfo(); + const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; if (CallsUnwindInit || MRI.isPhysRegModified(Reg)) - SavedRegs.set(Reg); + if (!NoCSR || !MRI.isAllocatable(Reg) || RI->isNeededForReturn(Reg, MF)) + SavedRegs.set(Reg); } } diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp index f75fe3740c7e7..b4fcb7da9bee2 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp @@ -267,6 +267,11 @@ MipsRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { return true; } +bool MipsRegisterInfo::isNeededForReturn(MCRegister PhysReg, const MachineFunction &MF) const { + return PhysReg == Mips::RA || PhysReg == Mips::RA_64 || PhysReg == Mips::RA_NM; +} + + // FrameIndex represent objects inside a abstract stack. // We must replace FrameIndex with an stack/frame pointer // direct reference. diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.h b/llvm/lib/Target/Mips/MipsRegisterInfo.h index b2a7dbb361484..feeba17303869 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.h +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.h @@ -73,6 +73,8 @@ class MipsRegisterInfo : public MipsGenRegisterInfo { /// Return GPR register class. virtual const TargetRegisterClass *intRegClass(unsigned Size) const = 0; + virtual bool isNeededForReturn(MCRegister PhysReg, const MachineFunction &MF) const override; + private: virtual void eliminateFI(MachineBasicBlock::iterator II, unsigned OpNo, int FrameIndex, uint64_t StackSize, From 4a74048fef9c2407d13a9758482e2ac9370c3f0f Mon Sep 17 00:00:00 2001 From: Colin McEwan Date: Mon, 26 Sep 2022 11:18:12 +0100 Subject: [PATCH 028/123] NanoMips: Fix immZExt7Plus1 conditions --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index b8295aa6c7dbe..780bd753aeb51 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -44,7 +44,7 @@ def immZExt12Plus1 : PatLeaf<(imm), [{ return isUInt<13>(N->getZExtValue()) && isUInt<12>(N->getZExtValue() + 1); }]>; def immZExt7Plus1 : PatLeaf<(imm), [{ - return isUInt<7>(N->getZExtValue()) && isUInt<12>(N->getZExtValue() + 1); + return isUInt<8>(N->getZExtValue()) && isUInt<7>(N->getZExtValue() + 1); }]>; // Immediate range for signed 12-bit def imm32SExt12OrZExt16 : IntImmLeaf(Imm.getSExtValue()) From 365a9ad1c6166651f352205219db1ab2338fe38a Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 25 Nov 2022 16:25:30 +0530 Subject: [PATCH 029/123] Add LUI and fix %hi/%lo operators --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 13 +- .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 112 ++++++++++++++++++ .../Target/Mips/MCTargetDesc/MipsFixupKinds.h | 4 +- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 30 ++++- .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 4 + .../Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 8 ++ .../lib/Target/Mips/MCTargetDesc/MipsMCExpr.h | 2 + llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 54 +++++++++ 9 files changed, 221 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 58e8f43823d35..a9d7acc4eb76e 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -771,13 +771,19 @@ class MipsAsmParser : public MCTargetAsmParser { case AsmToken::PercentGp_Rel: return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx); case AsmToken::PercentHi: - return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx); + if (hasNanoMips()) + return MipsMCExpr::create(MipsMCExpr::MEK_HI20, E, Ctx); + else + return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx); case AsmToken::PercentHigher: return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx); case AsmToken::PercentHighest: return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx); case AsmToken::PercentLo: - return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx); + if (hasNanoMips()) + return MipsMCExpr::create(MipsMCExpr::MEK_LO12, E, Ctx); + else + return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx); case AsmToken::PercentNeg: return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx); case AsmToken::PercentPcrel_Hi: @@ -6174,6 +6180,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_SImm32_Relaxed: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 32-bit signed immediate"); + case Match_SImm20s12: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 20-bit signed immediate"); case Match_UImm32_Coerced: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 32-bit immediate"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 4d45b60c1852f..5790f0b3c6b01 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -147,6 +147,8 @@ static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) { return ELF::R_MICROMIPS_LO16; if (Type == ELF::R_MIPS16_HI16) return ELF::R_MIPS16_LO16; + if (Type == ELF::R_NANOMIPS_HI20) + return ELF::R_NANOMIPS_LO12; if (Reloc.OriginalSymbol && Reloc.OriginalSymbol->getBinding() != ELF::STB_LOCAL) @@ -156,6 +158,8 @@ static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) { return ELF::R_MIPS_LO16; if (Type == ELF::R_MICROMIPS_GOT16) return ELF::R_MICROMIPS_LO16; + if (Type == ELF::R_NANOMIPS_GOTPC_HI20) + return ELF::R_NANOMIPS_GOT_LO12; if (Type == ELF::R_MIPS16_GOT16) return ELF::R_MIPS16_LO16; @@ -216,6 +220,110 @@ MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI, uint16_t EMachine, bool Is64) : MCELFObjectTargetWriter(Is64, OSABI, EMachine, HasRelocationAddend) {} + +static unsigned getNanoMipsRelocType(MCContext &Ctx, + const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) { + // Determine the type of the relocation. + unsigned Kind = Fixup.getTargetKind(); + + if (IsPCRel) { + switch (Kind) { + case Mips::fixup_NANOMIPS_PC25_S1: + return ELF::R_NANOMIPS_PC25_S1; + case Mips::fixup_NANOMIPS_PC21_S1: + return ELF::R_NANOMIPS_PC21_S1; + case Mips::fixup_NANOMIPS_PC14_S1: + return ELF::R_NANOMIPS_PC14_S1; + case Mips::fixup_NANOMIPS_PC11_S1: + return ELF::R_NANOMIPS_PC11_S1; + case Mips::fixup_NANOMIPS_PC10_S1: + return ELF::R_NANOMIPS_PC10_S1; + case Mips::fixup_NANOMIPS_PC7_S1: + return ELF::R_NANOMIPS_PC7_S1; + case Mips::fixup_NANOMIPS_PC4_S1: + return ELF::R_NANOMIPS_PC4_S1; + case Mips::fixup_NANOMIPS_PCHI20: + return ELF::R_NANOMIPS_PCHI20; + case Mips::fixup_NANOMIPS_PC_I32: + return ELF::R_NANOMIPS_PC_I32; + case Mips::fixup_NANOMIPS_GOTPC_I32: + return ELF::R_NANOMIPS_GOTPC_I32; + case Mips::fixup_NANOMIPS_GOTPC_HI20: + return ELF::R_NANOMIPS_GOTPC_HI20; + } + + llvm_unreachable("invalid PC-relative fixup kind!"); + } + + switch (Kind) { + case Mips::fixup_NANOMIPS_32: return ELF::R_NANOMIPS_32; + case Mips::fixup_NANOMIPS_64: return ELF::R_NANOMIPS_64; + case Mips::fixup_NANOMIPS_NEG: return ELF::R_NANOMIPS_NEG; + case Mips::fixup_NANOMIPS_ASHIFTR_1: return ELF::R_NANOMIPS_ASHIFTR_1; + case Mips::fixup_NANOMIPS_UNSIGNED_8: return ELF::R_NANOMIPS_UNSIGNED_8; + case Mips::fixup_NANOMIPS_SIGNED_8: return ELF::R_NANOMIPS_SIGNED_8; + case Mips::fixup_NANOMIPS_UNSIGNED_16: return ELF::R_NANOMIPS_UNSIGNED_16; + case Mips::fixup_NANOMIPS_SIGNED_16: return ELF::R_NANOMIPS_SIGNED_16; + case Mips::fixup_NANOMIPS_RELATIVE: return ELF::R_NANOMIPS_RELATIVE; + case Mips::fixup_NANOMIPS_GLOBAL: return ELF::R_NANOMIPS_GLOBAL; + case Mips::fixup_NANOMIPS_JUMP_SLOT: return ELF::R_NANOMIPS_JUMP_SLOT; + case Mips::fixup_NANOMIPS_IRELATIVE: return ELF::R_NANOMIPS_IRELATIVE; + case Mips::fixup_NANOMIPS_GPREL19_S2: return ELF::R_NANOMIPS_GPREL19_S2; + case Mips::fixup_NANOMIPS_GPREL18_S3: return ELF::R_NANOMIPS_GPREL18_S3; + case Mips::fixup_NANOMIPS_GPREL18: return ELF::R_NANOMIPS_GPREL18; + case Mips::fixup_NANOMIPS_GPREL17_S1: return ELF::R_NANOMIPS_GPREL17_S1; + case Mips::fixup_NANOMIPS_GPREL16_S2: return ELF::R_NANOMIPS_GPREL16_S2; + case Mips::fixup_NANOMIPS_GPREL7_S2: return ELF::R_NANOMIPS_GPREL7_S2; + case Mips::fixup_NANOMIPS_GPREL_HI20: return ELF::R_NANOMIPS_GPREL_HI20; + case Mips::fixup_NANOMIPS_HI20: return ELF::R_NANOMIPS_HI20; + case Mips::fixup_NANOMIPS_LO12: return ELF::R_NANOMIPS_LO12; + case Mips::fixup_NANOMIPS_GPREL_I32: return ELF::R_NANOMIPS_GPREL_I32; + case Mips::fixup_NANOMIPS_I32: return ELF::R_NANOMIPS_I32; + case Mips::fixup_NANOMIPS_GOT_DISP: return ELF::R_NANOMIPS_GOT_DISP; + case Mips::fixup_NANOMIPS_GOT_LO12: return ELF::R_NANOMIPS_GOT_LO12; + case Mips::fixup_NANOMIPS_GOT_CALL: return ELF::R_NANOMIPS_GOT_CALL; + case Mips::fixup_NANOMIPS_GOT_PAGE: return ELF::R_NANOMIPS_GOT_PAGE; + case Mips::fixup_NANOMIPS_GOT_OFST: return ELF::R_NANOMIPS_GOT_OFST; + case Mips::fixup_NANOMIPS_LO4_S2: return ELF::R_NANOMIPS_LO4_S2; + case Mips::fixup_NANOMIPS_GPREL_LO12: return ELF::R_NANOMIPS_GPREL_LO12; + case Mips::fixup_NANOMIPS_COPY: return ELF::R_NANOMIPS_COPY; + case Mips::fixup_NANOMIPS_ALIGN: return ELF::R_NANOMIPS_ALIGN; + case Mips::fixup_NANOMIPS_FILL: return ELF::R_NANOMIPS_FILL; + case Mips::fixup_NANOMIPS_MAX: return ELF::R_NANOMIPS_MAX; + case Mips::fixup_NANOMIPS_INSN32: return ELF::R_NANOMIPS_INSN32; + case Mips::fixup_NANOMIPS_FIXED: return ELF::R_NANOMIPS_FIXED; + case Mips::fixup_NANOMIPS_NORELAX: return ELF::R_NANOMIPS_NORELAX; + case Mips::fixup_NANOMIPS_RELAX: return ELF::R_NANOMIPS_RELAX; + case Mips::fixup_NANOMIPS_SAVERESTORE: return ELF::R_NANOMIPS_SAVERESTORE; + case Mips::fixup_NANOMIPS_INSN16: return ELF::R_NANOMIPS_INSN16; + case Mips::fixup_NANOMIPS_JALR32: return ELF::R_NANOMIPS_JALR32; + case Mips::fixup_NANOMIPS_JALR16: return ELF::R_NANOMIPS_JALR16; + case Mips::fixup_NANOMIPS_JUMPTABLE_LOAD: return ELF::R_NANOMIPS_JUMPTABLE_LOAD; + case Mips::fixup_NANOMIPS_FRAME_REG: return ELF::R_NANOMIPS_FRAME_REG; + // TLS relocations. + case Mips::fixup_NANOMIPS_TLS_DTPMOD: return ELF::R_NANOMIPS_TLS_DTPMOD; + case Mips::fixup_NANOMIPS_TLS_DTPREL: return ELF::R_NANOMIPS_TLS_DTPREL; + case Mips::fixup_NANOMIPS_TLS_TPREL: return ELF::R_NANOMIPS_TLS_TPREL; + case Mips::fixup_NANOMIPS_TLS_GD: return ELF::R_NANOMIPS_TLS_GD; + case Mips::fixup_NANOMIPS_TLS_GD_I32: return ELF::R_NANOMIPS_TLS_GD_I32; + case Mips::fixup_NANOMIPS_TLS_LD: return ELF::R_NANOMIPS_TLS_LD; + case Mips::fixup_NANOMIPS_TLS_LD_I32: return ELF::R_NANOMIPS_TLS_LD_I32; + case Mips::fixup_NANOMIPS_TLS_DTPREL12: return ELF::R_NANOMIPS_TLS_DTPREL12; + case Mips::fixup_NANOMIPS_TLS_DTPREL16: return ELF::R_NANOMIPS_TLS_DTPREL16; + case Mips::fixup_NANOMIPS_TLS_DTPREL_I32: return ELF::R_NANOMIPS_TLS_DTPREL_I32; + case Mips::fixup_NANOMIPS_TLS_GOTTPREL: return ELF::R_NANOMIPS_TLS_GOTTPREL; + case Mips::fixup_NANOMIPS_TLS_GOTTPREL_PC_I32: return ELF::R_NANOMIPS_TLS_GOTTPREL_PC_I32; + case Mips::fixup_NANOMIPS_TLS_TPREL12: return ELF::R_NANOMIPS_TLS_TPREL12; + case Mips::fixup_NANOMIPS_TLS_TPREL16: return ELF::R_NANOMIPS_TLS_TPREL16; + case Mips::fixup_NANOMIPS_TLS_TPREL_I32: return ELF::R_NANOMIPS_TLS_TPREL_I32; + } + + llvm_unreachable("invalid fixup kind!"); +} + + unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, @@ -223,6 +331,10 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, // Determine the type of the relocation. unsigned Kind = Fixup.getTargetKind(); + if (Kind >= Mips::FirstNanoMipsFixupKind + && Kind <= Mips::LastNanoMipsFixupKind) + return getNanoMipsRelocType(Ctx, Target, Fixup, IsPCRel); + switch (Kind) { case FK_NONE: return ELF::R_MIPS_NONE; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index 28fc324670f75..992479803a002 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -223,7 +223,8 @@ namespace Mips { fixup_MICROMIPS_JALR, // NanoMIPS relocations - fixup_NANOMIPS_32, + FirstNanoMipsFixupKind, + fixup_NANOMIPS_32 = FirstNanoMipsFixupKind, fixup_NANOMIPS_64, fixup_NANOMIPS_NEG, fixup_NANOMIPS_ASHIFTR_1, @@ -296,6 +297,7 @@ namespace Mips { fixup_NANOMIPS_TLS_TPREL12, fixup_NANOMIPS_TLS_TPREL16, fixup_NANOMIPS_TLS_TPREL_I32, + LastNanoMipsFixupKind = fixup_NANOMIPS_TLS_TPREL_I32, // Marker LastTargetFixupKind, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index ef259cdfe0ebd..c076821ef97bb 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -730,6 +730,20 @@ getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, return 0; } +unsigned MipsMCCodeEmitter:: +getSImm20Lsl12Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); + if (MO.isImm()) { + assert((Res & 0xfff) == 0); + return Res; + } + + return 0; +} + unsigned MipsMCCodeEmitter:: getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, @@ -823,14 +837,18 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, case MipsMCExpr::MEK_GPREL: FixupKind = Mips::fixup_Mips_GPREL16; break; + case MipsMCExpr::MEK_LO12: + FixupKind = Mips::fixup_NANOMIPS_LO12; + break; case MipsMCExpr::MEK_LO: // Check for %lo(%neg(%gp_rel(X))) if (MipsExpr->isGpOff()) FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO : Mips::fixup_Mips_GPOFF_LO; else - FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 - : Mips::fixup_Mips_LO16; + FixupKind = (isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 + : (isNanoMips(STI) ? Mips::fixup_NANOMIPS_LO12 + : Mips::fixup_Mips_LO16)); break; case MipsMCExpr::MEK_HIGHEST: FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST @@ -840,14 +858,18 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER : Mips::fixup_Mips_HIGHER; break; + case MipsMCExpr::MEK_HI20: + FixupKind = Mips::fixup_NANOMIPS_HI20; + break; case MipsMCExpr::MEK_HI: // Check for %hi(%neg(%gp_rel(X))) if (MipsExpr->isGpOff()) FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI : Mips::fixup_Mips_GPOFF_HI; else - FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 - : Mips::fixup_Mips_HI16; + FixupKind = (isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 + : (isNanoMips(STI) ? Mips::fixup_NANOMIPS_HI20 + : Mips::fixup_Mips_HI16)); break; case MipsMCExpr::MEK_PCREL_HI16: FixupKind = Mips::fixup_MIPS_PCHI16; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index ec18e4dfb0c6b..5d0b2ae9100fc 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -93,6 +93,10 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getSImm20Lsl12Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getSImm9AddiuspValue - Return binary encoding of the microMIPS addiusp // instruction immediate operand. unsigned getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp index c9560968edee8..eab5445c03d48 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -87,6 +87,7 @@ void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { OS << "%gp_rel"; break; case MEK_HI: + case MEK_HI20: OS << "%hi"; break; case MEK_HIGHER: @@ -96,6 +97,7 @@ void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { OS << "%highest"; break; case MEK_LO: + case MEK_LO12: OS << "%lo"; break; case MEK_NEG: @@ -205,6 +207,12 @@ MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res, case MEK_NEG: AbsVal = -AbsVal; break; + case MEK_HI20: + AbsVal = SignExtend64(AbsVal >> 12, 20); + break; + case MEK_LO12: + AbsVal = AbsVal & 0xfff; + break; } Res = MCValue::get(AbsVal); return true; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h index 60cda32558134..12fe984971914 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h @@ -46,6 +46,8 @@ class MipsMCExpr : public MCTargetExpr { MEK_TPREL_LO, MEK_Special, MEK_PCREL_HI, + MEK_HI20, + MEK_LO12, }; private: diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 6d1e90f82f3f3..bd9073e191695 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -121,7 +121,7 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, - LAGPB_NM, + LAGPB_NM, LUI_NM, LSA_NM, MOVEP_NM, MOVE_NM, MOD_NM, MODU_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MULu4x4_NM, NOT_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 780bd753aeb51..d56b4fec9db05 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -49,6 +49,9 @@ def immZExt7Plus1 : PatLeaf<(imm), [{ // Immediate range for signed 12-bit def imm32SExt12OrZExt16 : IntImmLeaf(Imm.getSExtValue()) || isUInt<16>(Imm.getZExtValue()); }]>; +// Immediate range for signed 20-bit upper part +def imm32SExt20s12 : IntImmLeaf(Imm.getSExtValue()) + && (Imm.getZExtValue() % 4096 == 0); }]>; class ConstantSImmRangeAsmOperandClass; def UImm3Plus1AsmOperandClass : ConstantUImmAsmOperandClass<3, [UImm5AsmOperandClass], 1>; +class SImmScaledAsmOperandClass Supers = []> + : AsmOperandClass{ + let Name = "SImm" # Bits # "s" # Align; + let RenderMethod = "addSImmOperands<32>"; + let PredicateMethod = "isSImm<" # Bits # ">"; + let SuperClasses = Supers; + let DiagnosticType = "SImm" # Bits # "s" # Align; +} + +def SImm32S12AsmOperandClass : SImmScaledAsmOperandClass<20, 12, []>; + class NMMemGPAsmOperand Supers = []> : AsmOperandClass { let Name = "NMMemGP" # Bits # "s" # Align; @@ -211,6 +225,12 @@ def jmptarget_nm : Operand { let ParserMatchClass = NMJumpTargetAsmOperand; } +def simm32s12_nm : Operand { +// let EncoderMethod = "getSImm20Lsl12Encoding"; + let PrintMethod = "printUImm<20>"; + let ParserMatchClass = SImmAsmOperandClass<20, []>; +} + def simm32power2 : IntImmLeaf; def uimm16_simm12 : Operand; @@ -614,6 +634,18 @@ class AddiU32 : + ArithLogicINM, _Pool_P32<0b00000> { + bits<5> rt; + bits<5> rs; + bits<16> imm; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...0} = imm; +} + class DivMod : ArithLogicR32_Desc { // Need to insert TEQ, because DIV(U)/MOD(U) don't trap on division by zero. @@ -1205,6 +1237,28 @@ def LAGPB_NM : RegImm48_Desc<"addiu.b", simm32_relaxed, GPR32NMOpnd>, } // isReMaterializable = 1 + +// Arithmetic and logical instructions with 2 register operands and immediate. +class LoadUpperINM : + InstNM<(outs RO:$rt), (ins Od:$imm), + !strconcat(opstr, "\t$rt, $imm"), + [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm))]> { + let isReMaterializable = 1; +} + +class LUI_Enc isel> : _Pool_P_LUI { + bits<5> rt; + bits<20> imm; + let Inst{25...21} = rt; + let Inst{20...12} = imm{8...0}; + let Inst{11...2} = imm{18...9}; + let Inst{0} = imm{19}; +} + +def LUI_NM : RegImmNM<"lui", simm32s12_nm, GPR32NMOpnd, imm32SExt20s12>, LUI_Enc<0b0>; + def ALUIPC_NM : RegImmNM<"aluipc", simm32_relaxed, GPR32NMOpnd>, InstSize32; def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPR32NMOpnd>, InstSize32; From fbdece5be6d7a6fd882e1cb48334746a7b1740be Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 26 Nov 2022 22:38:41 +0530 Subject: [PATCH 030/123] Fix ALUIPC encoding and fix %pcrel_hi operator --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 5 ++++- llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 2 ++ llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 6 +++--- llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 7 ++----- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index a9d7acc4eb76e..9d60aa364776d 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -787,7 +787,10 @@ class MipsAsmParser : public MCTargetAsmParser { case AsmToken::PercentNeg: return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx); case AsmToken::PercentPcrel_Hi: - return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx); + if (hasNanoMips()) + return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI, E, Ctx); + else + return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx); case AsmToken::PercentPcrel_Lo: return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx); case AsmToken::PercentTlsgd: diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 5790f0b3c6b01..d0a91c5946d6d 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -149,6 +149,8 @@ static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) { return ELF::R_MIPS16_LO16; if (Type == ELF::R_NANOMIPS_HI20) return ELF::R_NANOMIPS_LO12; + if (Type == ELF::R_NANOMIPS_PCHI20) + return ELF::R_NANOMIPS_LO12; if (Reloc.OriginalSymbol && Reloc.OriginalSymbol->getBinding() != ELF::STB_LOCAL) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index c076821ef97bb..afe8403996f70 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -874,6 +874,9 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, case MipsMCExpr::MEK_PCREL_HI16: FixupKind = Mips::fixup_MIPS_PCHI16; break; + case MipsMCExpr::MEK_PCREL_HI: + FixupKind = Mips::fixup_NANOMIPS_PCHI20; + break; case MipsMCExpr::MEK_PCREL_LO16: FixupKind = Mips::fixup_MIPS_PCLO16; break; @@ -897,9 +900,6 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; break; - case MipsMCExpr::MEK_PCREL_HI: - llvm_unreachable("nanoMIPS: NYI"); - break; } Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); return 0; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp index eab5445c03d48..ded4235df580e 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -163,8 +163,6 @@ MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res, if (Res.isAbsolute() && Fixup == nullptr) { int64_t AbsVal = Res.getConstant(); switch (Kind) { - case MEK_PCREL_HI: - llvm_unreachable("nanoMIPS: NYI"); case MEK_None: case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); @@ -189,6 +187,7 @@ MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res, case MEK_TLSLDM: case MEK_TPREL_HI: case MEK_TPREL_LO: + case MEK_PCREL_HI: return false; case MEK_LO: case MEK_CALL_LO16: @@ -262,9 +261,6 @@ static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { switch (getKind()) { - case MEK_PCREL_HI: - llvm_unreachable("nanoMIPS: NYI"); - break; case MEK_None: case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); @@ -286,6 +282,7 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { case MEK_NEG: case MEK_PCREL_HI16: case MEK_PCREL_LO16: + case MEK_PCREL_HI: // If we do have nested target-specific expressions, they will be in // a consecutive chain. if (const MipsMCExpr *E = dyn_cast(getSubExpr())) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index d56b4fec9db05..f59d5a0fecee1 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1259,7 +1259,7 @@ class LUI_Enc isel> : _Pool_P_LUI { def LUI_NM : RegImmNM<"lui", simm32s12_nm, GPR32NMOpnd, imm32SExt20s12>, LUI_Enc<0b0>; -def ALUIPC_NM : RegImmNM<"aluipc", simm32_relaxed, GPR32NMOpnd>, InstSize32; +def ALUIPC_NM : RegImmNM<"aluipc", simm32s12_nm, GPR32NMOpnd, imm32SExt20s12>, LUI_Enc<0b1>; def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPR32NMOpnd>, InstSize32; From 79d1d8f8c64ed8ee2c2de4a68389b62982554ed3 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 27 Nov 2022 23:29:16 +0530 Subject: [PATCH 031/123] Fix encoding and decoding for 48-bit instructions --- .../Target/Mips/Disassembler/MipsDisassembler.cpp | 14 +++++++------- .../Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 6 +++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 7437ee4ed874e..08683148d9e22 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1251,7 +1251,7 @@ static DecodeStatus readInstruction32(ArrayRef Bytes, uint64_t Address, /// Read four bytes from the ArrayRef and return 32 bit word sorted /// according to the given endianness. static DecodeStatus readInstruction48(ArrayRef Bytes, uint64_t Address, - uint64_t &Size, uint32_t &Insn, uint32_t &Insn2, + uint64_t &Size, uint64_t &Insn, bool IsBigEndian = false, bool IsNanoMips = true) { // We want to read exactly 6 Bytes of little-endian data in nanoMIPS mode. if (Bytes.size() < 6 || IsBigEndian || !IsNanoMips) { @@ -1266,9 +1266,9 @@ static DecodeStatus readInstruction48(ArrayRef Bytes, uint64_t Address, // nanoMIPS byte ordering: // Little-endian: 1 | 0 | 3 | 2 | 5 | 4 - Insn = (Bytes[4] << 0) | (Bytes[5] << 8) | (Bytes[2] << 16) - | (Bytes[3] << 24); - Insn2 = (Bytes[0] << 32) | (Bytes[1] << 40); + Insn = (Bytes[0] << 0) | (Bytes[1] << 8); + Insn = ((Insn << 32) | (Bytes[4] << 0) | (Bytes[5] << 8) | (Bytes[2] << 16) + | (Bytes[3] << 24)); return MCDisassembler::Success; } @@ -1281,7 +1281,7 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, Size = 0; if (IsNanoMips) { - uint32_t Insn2; + uint64_t Insn2; Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; @@ -1311,13 +1311,13 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, return Result; } - Result = readInstruction48(Bytes, Address, Size, Insn, Insn2, IsBigEndian, IsNanoMips); + Result = readInstruction48(Bytes, Address, Size, Insn2, IsBigEndian, IsNanoMips); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; LLVM_DEBUG(dbgs() << "Trying NanoMips48 table (48-bit instructions):\n"); // Calling the auto-generated decoder function. - Result = decodeInstruction(DecoderTableNanoMips48, Instr, Insn, Address, + Result = decodeInstruction(DecoderTableNanoMips48, Instr, Insn2, Address, this, STI); if (Result != MCDisassembler::Fail) { Size = 6; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index afe8403996f70..677fc64165f8a 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -143,6 +143,10 @@ void MipsMCCodeEmitter::emitInstruction(uint64_t Val, unsigned Size, if (IsLittleEndian && Size == 4 && (isMicroMips(STI) || isNanoMips(STI))) { emitInstruction(Val >> 16, 2, STI, OS); emitInstruction(Val, 2, STI, OS); + } else if (IsLittleEndian && Size == 6 && isNanoMips(STI)) { + emitInstruction(Val >> 32, 2, STI, OS); + emitInstruction(Val >> 16, 2, STI, OS); + emitInstruction(Val, 2, STI, OS); } else { for (unsigned i = 0; i < Size; ++i) { unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; @@ -184,7 +188,7 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, } unsigned long N = Fixups.size(); - uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); + uint64_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); // Check for unimplemented opcodes. // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 From e11f64089a8704026940e2dc46ca1ff8b41d9101 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 27 Nov 2022 23:33:01 +0530 Subject: [PATCH 032/123] Switch to RELA relocations and fix generic data relocations for nanoMIPS --- .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 61 +++++++++++++------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index d0a91c5946d6d..1661221910919 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -332,30 +332,51 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, bool IsPCRel) const { // Determine the type of the relocation. unsigned Kind = Fixup.getTargetKind(); + bool isNanoMips = Ctx.getTargetTriple().isNanoMips(); if (Kind >= Mips::FirstNanoMipsFixupKind && Kind <= Mips::LastNanoMipsFixupKind) return getNanoMipsRelocType(Ctx, Target, Fixup, IsPCRel); - switch (Kind) { - case FK_NONE: - return ELF::R_MIPS_NONE; - case FK_Data_1: - Ctx.reportError(Fixup.getLoc(), - "MIPS does not support one byte relocations"); - return ELF::R_MIPS_NONE; - case Mips::fixup_Mips_16: - case FK_Data_2: - return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16; - case Mips::fixup_Mips_32: - case FK_Data_4: - return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32; - case Mips::fixup_Mips_64: - case FK_Data_8: - return IsPCRel - ? setRTypes(ELF::R_MIPS_PC32, ELF::R_MIPS_64, ELF::R_MIPS_NONE) - : (unsigned)ELF::R_MIPS_64; - } + if (isNanoMips) + { + switch (Kind) { + case FK_NONE: + return ELF::R_NANOMIPS_NONE; + case FK_Data_1: + return ELF::R_NANOMIPS_UNSIGNED_8; + case FK_Data_2: + return ELF::R_NANOMIPS_UNSIGNED_16; + case FK_Data_4: + return ELF::R_NANOMIPS_32; + case FK_Data_8: + Ctx.reportError(Fixup.getLoc(), + "NanoMips does not support 8 byte relocations"); + return ELF::R_NANOMIPS_NONE; + } + } + else + { + switch (Kind) { + case FK_NONE: + return ELF::R_MIPS_NONE; + case FK_Data_1: + Ctx.reportError(Fixup.getLoc(), + "MIPS does not support one byte relocations"); + return ELF::R_MIPS_NONE; + case Mips::fixup_Mips_16: + case FK_Data_2: + return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16; + case Mips::fixup_Mips_32: + case FK_Data_4: + return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32; + case Mips::fixup_Mips_64: + case FK_Data_8: + return IsPCRel + ? setRTypes(ELF::R_MIPS_PC32, ELF::R_MIPS_64, ELF::R_MIPS_NONE) + : (unsigned)ELF::R_MIPS_64; + } + } if (IsPCRel) { switch (Kind) { @@ -780,7 +801,7 @@ std::unique_ptr llvm::createMipsELFObjectWriter(const Triple &TT, bool IsN32) { uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); bool IsN64 = TT.isArch64Bit() && !IsN32; - bool HasRelocationAddend = TT.isArch64Bit(); + bool HasRelocationAddend = (TT.isArch64Bit() || TT.getArch() == llvm::Triple::nanomips); uint16_t EMachine = ((TT.getArch() == llvm::Triple::nanomips)? ELF::EM_NANOMIPS : ELF::EM_MIPS); return std::make_unique(OSABI, HasRelocationAddend, From 5a536bddf06287ee15544fe0e6a5759d07aed3e9 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 19 Dec 2022 20:29:22 +0530 Subject: [PATCH 033/123] Update parsing for 48-bit instructions (LI/ADDIU) --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 58 +++++++++++++ .../Mips/MCTargetDesc/MipsAsmBackend.cpp | 8 +- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 56 +++++++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 12 +++ llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 6 ++ llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 3 + llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 11 +++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 3 + llvm/lib/Target/Mips/MipsScheduleGeneric.td | 1 + llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 81 ++++++++++++++----- 10 files changed, 215 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 9d60aa364776d..3ec1eb9c2745d 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1262,6 +1262,30 @@ class MipsOperand : public MCParsedAsmOperand { addConstantSImmOperands(Inst, N); } + void addSym32Operands(MCInst &Inst, unsigned N) const { + if (isImm() && !isConstantImm()) { + addExpr(Inst, getImm()); + return; + } + addConstantSImmOperands<32, 0, 0>(Inst, N); + } + + void addSym32PCRelOperands(MCInst &Inst, unsigned N) const { + if (isImm() && !isConstantImm()) { + addExpr(Inst, getImm()); + return; + } + addConstantSImmOperands<32, 0, 0>(Inst, N); + } + + void addSym32GPRelOperands(MCInst &Inst, unsigned N) const { + if (isImm() && !isConstantImm()) { + addExpr(Inst, getImm()); + return; + } + addConstantSImmOperands<32, 0, 0>(Inst, N); + } + template void addUImmOperands(MCInst &Inst, unsigned N) const { if (isImm() && !isConstantImm()) { @@ -1474,6 +1498,33 @@ class MipsOperand : public MCParsedAsmOperand { isShiftedUInt(getConstantImm()); } + bool isSym32() const { + MCValue Res; + bool Success; + if (Kind != k_Immediate) + return false; + Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr); + if (Success && Res.getRefKind() == MipsMCExpr::MEK_None) + return Success; + return Success; + } + + bool isSym32PCRel() const { + return isSym32(); + } + + bool isSym32GPRel() const { + MCValue Res; + bool Success; + if (Kind != k_Immediate) + return false; + + Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr); + if (Success && Res.getRefKind() == MipsMCExpr::MEK_GPREL) + return Success; + return false; + } + template bool isScaledSImm() const { if (isConstantImm() && @@ -6015,6 +6066,10 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) return Match_RequiresSameSrcAndDst; return Match_Success; + case Mips::ADDIU48_NM: + if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg()) + return Match_RequiresSameSrcAndDst; + return Match_Success; } uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags; @@ -6234,6 +6289,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(ErrorStart, "size plus position are not in the range 33 .. 64", SMRange(ErrorStart, ErrorEnd)); } + case Match_Sym32: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected symbol"); } llvm_unreachable("Implement any new match types added!"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 0af95bfb400d3..51753dff6124f 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -523,11 +523,11 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_NANOMIPS_HI20", 0, 20, 0 }, { "fixup_NANOMIPS_LO12", 0, 12, 0 }, { "fixup_NANOMIPS_GPREL_I32", 0, 32, 0 }, - { "fixup_NANOMIPS_PC_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_PC_I32", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_NANOMIPS_I32", 0, 32, 0 }, { "fixup_NANOMIPS_GOT_DISP", 0, 32, 0 }, - { "fixup_NANOMIPS_GOTPC_I32", 0, 32, 0 }, - { "fixup_NANOMIPS_GOTPC_HI20", 0, 32, 0 }, + { "fixup_NANOMIPS_GOTPC_I32", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_NANOMIPS_GOTPC_HI20", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_NANOMIPS_GOT_LO12", 0, 32, 0 }, { "fixup_NANOMIPS_GOT_CALL", 0, 32, 0 }, { "fixup_NANOMIPS_GOT_PAGE", 0, 32, 0 }, @@ -561,7 +561,7 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_NANOMIPS_TLS_DTPREL16", 0, 32, 0 }, { "fixup_NANOMIPS_TLS_DTPREL_I32", 0, 32, 0 }, { "fixup_NANOMIPS_TLS_GOTTPREL", 0, 32, 0 }, - { "fixup_NANOMIPS_TLS_GOTTPREL_PC_I32", 0, 32, 0 }, + { "fixup_NANOMIPS_TLS_GOTTPREL_PC_I32", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_NANOMIPS_TLS_TPREL12", 0, 32, 0 }, { "fixup_NANOMIPS_TLS_TPREL16", 0, 32, 0 }, { "fixup_NANOMIPS_TLS_TPREL_I32", 0, 32, 0 }, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 677fc64165f8a..1c5eb692289e8 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -761,6 +761,62 @@ getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, return 0; } +unsigned MipsMCCodeEmitter:: +getSymPCRel(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCExpr *Expr; + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isExpr()) { + Expr = MO.getExpr(); + Fixups.push_back(MCFixup::create(0, Expr, + MCFixupKind(Mips::fixup_NANOMIPS_PC_I32))); + } + else if (MO.isImm()) { + Expr = MCConstantExpr::create(static_cast(MO.getImm()), Ctx); + Fixups.push_back(MCFixup::create(0, Expr, + MCFixupKind(Mips::fixup_NANOMIPS_PC_I32))); + } + return 0; +} + +unsigned MipsMCCodeEmitter:: +getSymGPRel(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCExpr *Expr; + unsigned RegBits=getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI); + + assert(MI.getOperand(OpNo).isReg() && RegBits == 28); + const MCOperand MO = MI.getOperand(OpNo+1); + + if (MO.isExpr()) { + const MipsMCExpr *MipsExpr = cast(Expr); + assert (MipsExpr->getKind() == MipsMCExpr::MEK_GPREL); + Expr = MO.getExpr(); + } + else if (MO.isImm()) + Expr = MCConstantExpr::create(static_cast(MO.getImm()), Ctx); + + Fixups.push_back(MCFixup::create(0, Expr, + MCFixupKind(Mips::fixup_NANOMIPS_GPREL_I32))); + return 0; +} + +unsigned MipsMCCodeEmitter:: +getSymAbs(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isExpr()) + Fixups.push_back(MCFixup::create(0, MO.getExpr(), + MCFixupKind(Mips::fixup_NANOMIPS_I32))); + else if (MO.isImm()) + return MO.getImm(); + return 0; +} + unsigned MipsMCCodeEmitter:: getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 5d0b2ae9100fc..01a9577ab7174 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -309,6 +309,18 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getSymPCRel(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getSymGPRel(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getSymAbs(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 3b175a8a9cfe1..9146beab2ea4d 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -85,6 +85,12 @@ bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, return false; } +bool MipsDAGToDAGISel::selectAddrSym(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const { llvm_unreachable("Unimplemented function."); diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 6f0a1ef2d69ce..62ef8fdab4e14 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -62,6 +62,9 @@ class MipsDAGToDAGISel : public SelectionDAGISel { virtual bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset) const; + virtual bool selectAddrSym(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + /// Match integer address pattern. virtual bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const; diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 7f37e0e21d074..f0befed36c28f 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -366,6 +366,17 @@ bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, return true; } +bool MipsSEDAGToDAGISel::selectAddrSym(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return false; + if (Addr.getOpcode() != ISD::TargetExternalSymbol && + Addr.getOpcode() != ISD::TargetGlobalAddress) + return false; + Base = Addr; + Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType()); + return true; +} + bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const { return selectAddrRegImm(Addr, Base, Offset) || diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index f9c4e463ed8c7..b43e1d154ae79 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -53,6 +53,9 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel { bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + bool selectAddrSym(SDValue Addr, SDValue &Base, + SDValue &Offset) const override; + bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const override; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index bd9073e191695..094de5017a143 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -118,6 +118,7 @@ def : InstRW<[GenericWriteALU], (instrs ADDIUPC_MMR6, ADDIU_MMR6, ADDU16_MMR6, def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ADDiu_NM, ADDIU48_NM, + ADDIUPC48_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index f59d5a0fecee1..c3ecbcdb585b3 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -90,21 +90,32 @@ class SImmScaledAsmOperandClass Super let DiagnosticType = "SImm" # Bits # "s" # Align; } +class SymAsmOperandClass + : AsmOperandClass{ + let Name = "Sym32" # Type ; + let DiagnosticType = "Sym32" # Type; + let PredicateMethod = "isSym32" # Type; +} + +def SymAsmOperandAbs : SymAsmOperandClass; +def SymAsmOperandPCRel : SymAsmOperandClass<"PCRel">; +def SymAsmOperandGPRel : SymAsmOperandClass<"GPRel">; + def SImm32S12AsmOperandClass : SImmScaledAsmOperandClass<20, 12, []>; -class NMMemGPAsmOperand Supers = []> - : AsmOperandClass { +class NMMemGPAsmOperand Supers = [MipsMemAsmOperand]> + : MipsMemSimmAsmOperand { let Name = "NMMemGP" # Bits # "s" # Align; let RenderMethod = "addMemOperands"; - let SuperClasses = Supers; + let ParserMethod = "parseMemOperand"; + let SuperClasses = Supers; let PredicateMethod = "isMemWithUimmOffsetGP<" # Bits # "," # Align # ">"; } -class NMMemSPAsmOperand Supers = []> +class NMMemSPAsmOperand : AsmOperandClass { let Name = "NMMemSP" # Bits # "s" # Align; let RenderMethod = "addMemOperands"; - let SuperClasses = Supers; let PredicateMethod = "isMemWithUimmOffsetSP<" # Bits # "," # Align # ">"; } @@ -231,6 +242,21 @@ def simm32s12_nm : Operand { let ParserMatchClass = SImmAsmOperandClass<20, []>; } +def sym32_pc_nm : Operand { + let EncoderMethod = "getSymPCRel"; + let ParserMatchClass = SymAsmOperandPCRel; +} + +def sym32_gp_nm : Operand { + let EncoderMethod = "getSymGPRel"; + let ParserMatchClass = SymAsmOperandGPRel; +} + +def sym32_abs_nm : Operand { + let EncoderMethod = "getSymAbs"; + let ParserMatchClass = SymAsmOperandAbs; +} + def simm32power2 : IntImmLeaf; def uimm16_simm12 : Operand; @@ -248,7 +274,8 @@ def addrgp18 : ComplexPattern; def addrgp17s1 : ComplexPattern; def addrgp7s2 : ComplexPattern; def addrsp5s2 : ComplexPattern; -def addrpcrel : ComplexPattern; +def addrpcrel : ComplexPattern; +def addrgprel : ComplexPattern; def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N->getZExtValue()), SDLoc(N), MVT::i32); @@ -947,7 +974,7 @@ class StoreMemoryNM16 isel> : _Pool_P48I { +class Op48_Enc isel> : _Pool_P48I { bits<5> rt; bits<32> addr; let Inst{41...37} = rt; @@ -1098,6 +1125,21 @@ class ReverseNM: InstNM<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), [(set RO:$rd, (OpNode RO:$rs))]>, InstSize32; +class LoadAddressPCRelNM : + InstNM<(outs RO:$rt), (ins MO:$addr), + !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, Addr:$addr)]>; + +class LoadAddressGPRelNM : + InstNM<(outs RO:$rt), (ins MO:$addr), + !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, Addr:$addr)]>; + +class LoadAddressAbsNM : + InstNM<(outs RO:$rt), (ins MO:$addr), + !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, Addr:$addr)]>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -1191,9 +1233,11 @@ def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPR32NMOpnd, imm32SExt12OrZExt16, add>; -let Constraints = "$rt = $rs" in -def ADDIU48_NM : ArithLogicINM<"addiu[48]", simm32_relaxed, GPR32NMOpnd, - imm32_NM, add>, RegImm48_Enc<0b00001>; +def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPR32NMOpnd, + imm32_NM, add>, Op48_Enc<0b00001>; + +def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPR32NMOpnd, sym32_pc_nm, + addrpcrel>, Op48_Enc<0b00011>; def LSA_NM : LoadScaledAddressNM<"lsa", GPR32NMOpnd>; @@ -1224,16 +1268,13 @@ def JRC_NM : IndirectBranchNM<"jrc", GPR32NMOpnd>; def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { -def Li_NM : RegImm48_Desc<"li", simm32_relaxed, GPR32NMOpnd>, - RegImm48_Enc<0b00000>; +def Li_NM : LoadAddressAbsNM<"li48", GPR32NMOpnd, sym32_abs_nm, + addrpcrel>, Op48_Enc<0b00000>; def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPR32NMOpnd>, - RegImm48_Enc<0b00011>; + Op48_Enc<0b00011>; -def LAGPB_NM : RegImm48_Desc<"addiu.b", simm32_relaxed, GPR32NMOpnd>, - RegImm48_Enc<0b00010> { - let AsmString = "addiu.b $rt, $$gp, %gprel( $imm )"; - let isReMaterializable = 1; -} +def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPR32NMOpnd, sym32_gp_nm, + addrgprel>, Op48_Enc<0b00010>; } // isReMaterializable = 1 @@ -1694,8 +1735,8 @@ def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000> //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; -def SWPC_NM : StorePCBase, LSMem_PC48_Enc<0b01011>; -def LWPC_NM : LoadPCBase, LSMem_PC48_Enc<0b01111>; +def SWPC_NM : StorePCBase, Op48_Enc<0b01011>; +def LWPC_NM : LoadPCBase, Op48_Enc<0b01111>; let isCodeGenOnly = 1 in { From 0de3cd78c5b87702e0cadb1a0aec2cf5089f2175 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 19 Dec 2022 20:48:28 +0530 Subject: [PATCH 034/123] Refactor AsmParser and improve check of memory addressing with $gp --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 3ec1eb9c2745d..bdb258faac670 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1480,10 +1480,29 @@ class MipsOperand : public MCParsedAsmOperand { && (getMemBase()->getGPR32Reg() == Mips::GP); } + MipsOperand *getMemBase() const { + assert((Kind == k_Memory) && "Invalid access!"); + return Mem.Base; + } + + const MCExpr *getMemOff() const { + assert((Kind == k_Memory) && "Invalid access!"); + return Mem.Off; + } + + int64_t getConstantMemOff() const { + return static_cast(getMemOff())->getValue(); + } + template bool isMemWithUimmOffsetGP() const { - return isMem() && isConstantMemOff() && isUInt(getConstantMemOff()) - && (getConstantMemOff() % Align == 0) && getMemBase()->isRegIdx() - && (getMemBase()->getGPR32Reg() == Mips::GP); + if (isMem() && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::GP)) { + MCValue Res; + bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + + return (IsReloc || (isConstantMemOff() && isUInt(getConstantMemOff()) + && (getConstantMemOff() % Align == 0))); + } + return false; } template bool isMemWithUimmOffsetSP() const { @@ -1603,20 +1622,6 @@ class MipsOperand : public MCParsedAsmOperand { return Value; } - MipsOperand *getMemBase() const { - assert((Kind == k_Memory) && "Invalid access!"); - return Mem.Base; - } - - const MCExpr *getMemOff() const { - assert((Kind == k_Memory) && "Invalid access!"); - return Mem.Off; - } - - int64_t getConstantMemOff() const { - return static_cast(getMemOff())->getValue(); - } - const SmallVectorImpl &getRegList() const { assert((Kind == k_RegList) && "Invalid access!"); return *(RegList.List); From 7a58aed52a7d72cb987e5c05b7d708bde852eab9 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 19 Dec 2022 21:13:38 +0530 Subject: [PATCH 035/123] Add a nanoMIPS parser variant to allow brackets in mnemonics --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 8 ++++++-- llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 2 ++ llvm/lib/Target/Mips/MicroMipsInstrFormats.td | 1 + llvm/lib/Target/Mips/Mips.td | 12 ++++++++++-- llvm/lib/Target/Mips/Mips16InstrFormats.td | 1 + llvm/lib/Target/Mips/MipsInstrFormats.td | 1 + llvm/lib/Target/Mips/NanoMipsInstrFormats.td | 1 + 7 files changed, 22 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index bdb258faac670..ad115896c9bd7 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" @@ -6103,8 +6104,10 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, uint64_t &ErrorInfo, bool MatchingInlineAsm) { MCInst Inst; - unsigned MatchResult = - MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); + unsigned MatchResult; + int VariantId = getContext().getAsmInfo()->getAssemblerDialect(); + + MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, VariantId); switch (MatchResult) { case Match_Success: @@ -9135,6 +9138,7 @@ bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) { switch (VariantID) { default: llvm_unreachable("invalid variant!"); case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break; + case 1: Start = std::begin(MatchTable1); End = std::end(MatchTable1); break; } // Search the table. auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode()); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp index c1f1944941541..b957c025771b2 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp @@ -52,4 +52,6 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple, HasMipsExpressions = true; if (ABI.IsP32()) HasLEB128Directives = false; + if (TheTriple.isNanoMips()) + AssemblerDialect = 1; } diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td index 101d080f95674..12a1b157a88bf 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td @@ -31,6 +31,7 @@ class MicroMipsInstBase pattern, let Pattern = pattern; let Itinerary = itin; + let AsmVariantName = "mips"; let EncodingPredicates = [InMicroMips]; Format Form = f; diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index c816d112ade14..e8ed031d9f7aa 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -280,18 +280,26 @@ def MipsAsmParser : AsmParser { def MipsAsmParserVariant : AsmParserVariant { int Variant = 0; - + string Name = "mips"; // Recognize hard coded registers. string RegisterPrefix = "$"; } +def NanoMipsAsmParserVariant : AsmParserVariant { + int Variant = 1; + string Name = "nanomips"; + string TokenizingCharacters = "*!"; + string RegisterPrefix = "$"; +} + def Mips : Target { let InstructionSet = MipsInstrInfo; let AssemblyParsers = [MipsAsmParser]; - let AssemblyParserVariants = [MipsAsmParserVariant]; + let AssemblyParserVariants = [MipsAsmParserVariant, NanoMipsAsmParserVariant]; let AllowRegisterRenaming = 1; } + //===----------------------------------------------------------------------===// // Pfm Counters //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Mips/Mips16InstrFormats.td b/llvm/lib/Target/Mips/Mips16InstrFormats.td index f4ac160c2ba57..bc5642433418f 100644 --- a/llvm/lib/Target/Mips/Mips16InstrFormats.td +++ b/llvm/lib/Target/Mips/Mips16InstrFormats.td @@ -45,6 +45,7 @@ class MipsInst16_Base pattern, let Pattern = pattern; let Itinerary = itin; + let AsmVariantName = "mips"; let Predicates = [InMips16Mode]; } diff --git a/llvm/lib/Target/Mips/MipsInstrFormats.td b/llvm/lib/Target/Mips/MipsInstrFormats.td index 10529c7d9e192..c841aa4d9b5fc 100644 --- a/llvm/lib/Target/Mips/MipsInstrFormats.td +++ b/llvm/lib/Target/Mips/MipsInstrFormats.td @@ -106,6 +106,7 @@ class MipsInst pattern, let TSFlags{5} = hasForbiddenSlot; let TSFlags{6} = hasFCCRegOperand; + let AsmVariantName = "mips"; let DecoderNamespace = "Mips"; field bits<32> SoftFail = 0; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrFormats.td b/llvm/lib/Target/Mips/NanoMipsInstrFormats.td index 11f6d44899dfc..f5a2dfedbcb09 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrFormats.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrFormats.td @@ -8,6 +8,7 @@ class InstNM pattern, string Arch = "nanomips"; let OutOperandList = outs; let InOperandList = ins; + let AsmVariantName = "nanomips"; let AsmString = asmstr; let Pattern = pattern; From 319f5b4ce4baddb2b372f352ce206c5682946077 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 19 Dec 2022 22:59:45 +0530 Subject: [PATCH 036/123] Revert "TableGen hack to prefer smaller instructions" This reverts commit 99c5a0a2fa1ee94a3dceff46d1603523cce229de. --- llvm/utils/TableGen/AsmMatcherEmitter.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index 712c7ce1e1fd4..00bdd127e3c28 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -615,13 +615,6 @@ struct MatchableInfo { if (int Cmp = Mnemonic.compare_insensitive(RHS.Mnemonic)) return Cmp == -1; - // Compare the size of the instructions. - const CodeGenInstruction *ResultInst = getResultInst(); - uint64_t LHSSize = getResultInst()->TheDef->getValueAsInt("Size"); - uint64_t RHSSize = RHS.getResultInst()->TheDef->getValueAsInt("Size"); - if (LHSSize != RHSSize) - return LHSSize < RHSSize; - if (AsmOperands.size() != RHS.AsmOperands.size()) return AsmOperands.size() < RHS.AsmOperands.size(); From b303eb939c8011ada5c1af834c31abe787c1784e Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 20 Dec 2022 10:11:23 +0530 Subject: [PATCH 037/123] Clean-up extra instruction suffixes for 16-bit arithmetic --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 33 +++++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 094de5017a143..7302abe6cefd3 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -124,7 +124,7 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, LAGPB_NM, LUI_NM, LSA_NM, MOVEP_NM, MOVE_NM, MOD_NM, MODU_NM, - MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MULu4x4_NM, + MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, NOT_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, ROTR_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, SLLV_NM, SLT_NM, SLTI_NM, SLTIU_NM, SLTU_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index c3ecbcdb585b3..8ff3e3de99cf8 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1146,17 +1146,6 @@ class LoadAddressAbsNM, - AddSubR16_Enc<0b0>; -def SUBu16_NM : AddSubR16_Desc<"subu", GPR3Opnd, sub>, - AddSubR16_Enc<0b1>; -def ADDu4x4_NM : Arith4x4_Desc<"addu4 x4", GPR4Opnd, add>, - Arith4x4_Enc<0b00>; -def MULu4x4_NM : Arith4x4_Desc<"mulu", GPR4Opnd, mul>, - Arith4x4_Enc<0b01>; -} // _POOL32A0_0 pool of instructions. def SLLV_NM : ArithLogicR32_Desc<"sllv", GPR32NMOpnd, shl>, @@ -1204,6 +1193,18 @@ def DIVU_NM : DivMod<"divu", udiv>, def MODU_NM : DivMod<"modu", urem>, ArithLogicR32_Enc<0b011111>; +// 16-bit register operations +let FastISelShouldIgnore = 1 in { +def ADDu16_NM : AddSubR16_Desc<"addu", GPR3Opnd, add>, + AddSubR16_Enc<0b0>; +def SUBu16_NM : AddSubR16_Desc<"subu", GPR3Opnd, sub>, + AddSubR16_Enc<0b1>; +def ADDu4x4_NM : Arith4x4_Desc<"addu", GPR4Opnd, add>, + Arith4x4_Enc<0b00>; +def MUL4x4_NM : Arith4x4_Desc<"mul", GPR4Opnd, mul>, + Arith4x4_Enc<0b01>; +} + // P.U12 pool of instructions def ORI_NM : CondLogicI32_Desc<"ori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, or>, CondLogicI32_Enc<0b0000>; @@ -1254,13 +1255,13 @@ def BYTEREVW_NM : ReverseNM<"byterevw", GPR32NMOpnd, bswap>; def TEQ_NM : Trap_Desc<"teq", GPR32NMOpnd, uimm5_nm>, Trap_Enc<0b0>; def TNE_NM : Trap_Desc<"tne", GPR32NMOpnd, uimm5_nm>, Trap_Enc<0b1>; -def NOT_NM : ArithLogicR16U_Desc<"not16", GPR3Opnd, not>, +def NOT_NM : ArithLogicR16U_Desc<"not", GPR3Opnd, not>, ArithLogicR16_Enc<0b00>; -def XOR16_NM : ArithLogicR16_Desc<"xor16", GPR3Opnd>, +def XOR16_NM : ArithLogicR16_Desc<"xor", GPR3Opnd>, ArithLogicR16_Enc<0b01>; -def AND16_NM : ArithLogicR16_Desc<"and16", GPR3Opnd>, +def AND16_NM : ArithLogicR16_Desc<"and", GPR3Opnd>, ArithLogicR16_Enc<0b10>; -def OR16_NM : ArithLogicR16_Desc<"or16", GPR3Opnd>, +def OR16_NM : ArithLogicR16_Desc<"or ", GPR3Opnd>, ArithLogicR16_Enc<0b11>; def JRC_NM : IndirectBranchNM<"jrc", GPR32NMOpnd>; @@ -1268,7 +1269,7 @@ def JRC_NM : IndirectBranchNM<"jrc", GPR32NMOpnd>; def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { -def Li_NM : LoadAddressAbsNM<"li48", GPR32NMOpnd, sym32_abs_nm, +def Li_NM : LoadAddressAbsNM<"li", GPR32NMOpnd, sym32_abs_nm, addrpcrel>, Op48_Enc<0b00000>; def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPR32NMOpnd>, Op48_Enc<0b00011>; From c6ef6c9794881c459062d8bbba2a9fb8731c329f Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 20 Dec 2022 10:12:19 +0530 Subject: [PATCH 038/123] Add more load/store instructions to nanoMIPS load/store optimizer --- .../Target/Mips/NanoMipsLoadStoreOptimizer.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index e644f9f638dbe..dbdb0380cf80f 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -575,6 +575,12 @@ static bool isValidUse(MachineInstr *MI, Register Reg) { case Mips::LW_NM: case Mips::LWs9_NM: case Mips::ADDiu_NM: + case Mips::LH16_NM: + case Mips::LHU16_NM: + case Mips::SH16_NM: + case Mips::LB16_NM: + case Mips::LBU16_NM: + case Mips::SB16_NM: return MI->getOperand(1).getReg() == Reg; default: return false; @@ -589,6 +595,18 @@ static bool isLoadStoreShortChar(MachineInstr *MI) { case Mips::SH_NM: case Mips::LH_NM: case Mips::LHU_NM: + case Mips::LH16_NM: + case Mips::LHU16_NM: + case Mips::SH16_NM: + case Mips::LHGP_NM: + case Mips::LHUGP_NM: + case Mips::SHGP_NM: + case Mips::LB16_NM: + case Mips::LBU16_NM: + case Mips::SB16_NM: + case Mips::LBGP_NM: + case Mips::LBUGP_NM: + case Mips::SBGP_NM: return true; default: return false; From 885d256c21654e58f0e4367be245ebe0cacded14 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 20 Dec 2022 10:13:37 +0530 Subject: [PATCH 039/123] Fix descriptor calls for scaled loads & stores --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 8ff3e3de99cf8..5735e682851c2 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1696,32 +1696,32 @@ def LBUs9_NM : LoadMemoryNM<"lbu", mem_nms9, zextloadi8, addrsimm9, II_LBU>, def LHUs9_NM : LoadMemoryNM<"lhu", mem_nms9, zextloadi16, addrsimm9, II_LHU>, LSMem_S9_Enc<0b000, 0b0110>; -def LBX_NM : LoadMemoryNM<"lbx", mem_nmrx, sextloadi8, addrindexed, II_LB>, +def LBX_NM : LoadMemoryX<"lbx", mem_nmrx, sextloadi8, addrindexed, II_LB>, LSMemX_Enc<0, 0b0000>; -def SBX_NM : StoreMemoryNM<"sbx", mem_nmrx, truncstorei8, addrindexed, II_SB>, +def SBX_NM : StoreMemoryX<"sbx", mem_nmrx, truncstorei8, addrindexed, II_SB>, LSMemX_Enc<0, 0b0001>; -def LHX_NM : LoadMemoryNM<"lhx", mem_nmrx, sextloadi16, addrindexed, II_LH>, +def LHX_NM : LoadMemoryX<"lhx", mem_nmrx, sextloadi16, addrindexed, II_LH>, LSMemX_Enc<0, 0b0100>; -def SHX_NM : StoreMemoryNM<"shx", mem_nmrx, truncstorei16, addrindexed, II_SH>, +def SHX_NM : StoreMemoryX<"shx", mem_nmrx, truncstorei16, addrindexed, II_SH>, LSMemX_Enc<0, 0b0101>; def LWX_NM : LoadMemoryX<"lwx", mem_nmrx, load, addrindexed, II_LW>, LSMemX_Enc<0, 0b1000>; -def SWX_NM : StoreMemoryNM<"swx", mem_nmrx, store, addrindexed, II_SW>, +def SWX_NM : StoreMemoryX<"swx", mem_nmrx, store, addrindexed, II_SW>, LSMemX_Enc<0, 0b1001>; -def LBUX_NM : LoadMemoryNM<"lbux", mem_nmrx, zextloadi8, addrindexed, II_LBU>, +def LBUX_NM : LoadMemoryX<"lbux", mem_nmrx, zextloadi8, addrindexed, II_LBU>, LSMemX_Enc<0, 0b0010>; -def LHUX_NM : LoadMemoryNM<"lhux", mem_nmrx, zextloadi16, addrindexed, II_LHU>, +def LHUX_NM : LoadMemoryX<"lhux", mem_nmrx, zextloadi16, addrindexed, II_LHU>, LSMemX_Enc<0, 0b0000>; -def LHXS_NM : LoadMemoryNM<"lhxs", mem_nmrx, sextloadi16, addrindexedlsl1, II_LH>, +def LHXS_NM : LoadMemoryX<"lhxs", mem_nmrx, sextloadi16, addrindexedlsl1, II_LH>, LSMemX_Enc<0b1, 0b0100>; -def SHXS_NM : StoreMemoryNM<"shxs", mem_nmrx, truncstorei16, addrindexedlsl1, II_SH>, +def SHXS_NM : StoreMemoryX<"shxs", mem_nmrx, truncstorei16, addrindexedlsl1, II_SH>, LSMemX_Enc<0b1, 0b0101>; -def LHUXS_NM : LoadMemoryNM<"lhuxs", mem_nmrx, zextloadi16, addrindexedlsl1, II_LHU>, +def LHUXS_NM : LoadMemoryX<"lhuxs", mem_nmrx, zextloadi16, addrindexedlsl1, II_LHU>, LSMemX_Enc<0b1, 0b0110>; -def LWXS_NM : LoadMemoryNM<"lwxs", mem_nmrx, load, addrindexedlsl2, II_LW>, +def LWXS_NM : LoadMemoryX<"lwxs", mem_nmrx, load, addrindexedlsl2, II_LW>, LSMemX_Enc<0b1, 0b1000>; -def SWXS_NM : StoreMemoryNM<"swxs", mem_nmrx, store, addrindexedlsl2, II_SW>, +def SWXS_NM : StoreMemoryX<"swxs", mem_nmrx, store, addrindexedlsl2, II_SW>, LSMemX_Enc<0b1, 0b1001>; def UALH_NM : UnalignedLoad<"ualh", NMUnalignedLH>, LSMem_S9_Enc<0b001, 0b0100>; @@ -1804,12 +1804,12 @@ def : NMPat<(store GPR32NM:$rt, GPR32NM:$rs), // Any-extending loads def : NMPat<(i32 (extloadi8 addruimm12:$addr)), (LBU_NM addruimm12:$addr)>; def : NMPat<(i32 (extloadi8 addrsimm9:$addr)), (LBUs9_NM addrsimm9:$addr)>; -def : NMPat<(i32 (extloadi8 addrindexed:$addr)), (LBUX_NM addrindexed:$addr)>; +def : NMPat<(i32 (extloadi8 addrindexed:$addr)), (LBUX_NM addrindexed:$addr, 0)>; def : NMPat<(i32 (extloadi16 addruimm12:$addr)), (LHU_NM addruimm12:$addr)>; def : NMPat<(i32 (extloadi16 addrsimm9:$addr)), (LHUs9_NM addrsimm9:$addr)>; def : NMPat<(i32 (extloadi16 addrindexedlsl1:$addr)), - (LHUXS_NM addrindexedlsl1:$addr)>; -def : NMPat<(i32 (extloadi16 addrindexed:$addr)), (LHUX_NM addrindexed:$addr)>; + (LHUXS_NM addrindexedlsl1:$addr, 0)>; +def : NMPat<(i32 (extloadi16 addrindexed:$addr)), (LHUX_NM addrindexed:$addr, 0)>; // Catching out-of-range immediate unaligned loads/stores. def : NMPat<(i32 (NMUnalignedLW GPR32NM:$rs, GPR32NM:$src)), From d805060bd5aaa6d0e767addd7796e70a101a8206 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 20 Dec 2022 19:33:43 +0530 Subject: [PATCH 040/123] Add register constraints on 16-bit logic and arithmetic --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index ad115896c9bd7..2281df902a09a 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -6069,10 +6069,14 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { case Mips::CRC32H: case Mips::CRC32CH: case Mips::CRC32W: case Mips::CRC32CW: case Mips::CRC32D: case Mips::CRC32CD: + case Mips::AND16_NM: case Mips::OR16_NM: + case Mips::XOR16_NM: if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) return Match_RequiresSameSrcAndDst; return Match_Success; case Mips::ADDIU48_NM: + case Mips::ADDu4x4_NM: + case Mips::MUL4x4_NM: if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg()) return Match_RequiresSameSrcAndDst; return Match_Success; From 9dade0a5299b1fd111a3e8240148ea31816564c9 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Wed, 21 Dec 2022 15:13:26 +0530 Subject: [PATCH 041/123] Refactor register class names for consistency --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 9 +- .../Mips/Disassembler/MipsDisassembler.cpp | 40 +- llvm/lib/Target/Mips/MipsISelLowering.cpp | 4 +- llvm/lib/Target/Mips/MipsInstrInfo.cpp | 2 +- llvm/lib/Target/Mips/MipsRegisterInfo.cpp | 8 +- llvm/lib/Target/Mips/MipsRegisterInfo.td | 41 +- llvm/lib/Target/Mips/MipsSEFrameLowering.cpp | 6 +- llvm/lib/Target/Mips/MipsSEISelLowering.cpp | 2 +- llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 10 +- llvm/lib/Target/Mips/MipsSERegisterInfo.cpp | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 388 +++++++++--------- .../Mips/NanoMipsLoadStoreOptimizer.cpp | 2 +- 12 files changed, 262 insertions(+), 252 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 2281df902a09a..46fe7576f27d6 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1101,15 +1101,16 @@ class MipsOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(getGPR32Reg())); } - void addGPR32NMAsmRegOperands(MCInst &Inst, unsigned N) const { - addGPR32AsmRegOperands(Inst, N); - } - void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); } + void addGPRNM32AsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addGPR32AsmRegOperands(Inst, N); + } + void addGPRNM16AsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createReg(getGPR32Reg())); diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 08683148d9e22..536ff6188f327 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -111,20 +111,20 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeGPR3RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); +static DecodeStatus DecodeGPRNM3RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); -static DecodeStatus DecodeGPR4RegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); +static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); -static DecodeStatus DecodeGPR32NMRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder); +static DecodeStatus DecodeGPRNM32RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn, @@ -1564,32 +1564,32 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, return MCDisassembler::Success; } -static DecodeStatus DecodeGPR3RegisterClass(MCInst &Inst, +static DecodeStatus DecodeGPRNM3RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 7) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::GPR3RegClassID, RegNo); + unsigned Reg = getReg(Decoder, Mips::GPRNM3RegClassID, RegNo); Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } -static DecodeStatus DecodeGPR4RegisterClass(MCInst &Inst, +static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 15) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::GPR4RegClassID, RegNo); + unsigned Reg = getReg(Decoder, Mips::GPRNM4RegClassID, RegNo); Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } -static DecodeStatus DecodeGPR32NMRegisterClass(MCInst &Inst, - unsigned RegNo, - uint64_t Address, - const void *Decoder) { +static DecodeStatus DecodeGPRNM32RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); } diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index c92e4577eed97..f566f714c6de1 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -4607,12 +4607,12 @@ MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, if (Subtarget.inMips16Mode()) return std::make_pair(0U, &Mips::CPU16RegsRegClass); if (Subtarget.hasNanoMips()) - return std::make_pair(0U, &Mips::GPR32NMRegClass); + return std::make_pair(0U, &Mips::GPRNM32RegClass); return std::make_pair(0U, &Mips::GPR32RegClass); } if (VT == MVT::i64 && !Subtarget.isGP64bit()) return std::make_pair(0U, Subtarget.hasNanoMips() - ? &Mips::GPR32NMRegClass + ? &Mips::GPRNM32RegClass : &Mips::GPR32RegClass); if (VT == MVT::i64 && Subtarget.isGP64bit()) return std::make_pair(0U, &Mips::GPR64RegClass); diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index 3184bb86ae632..d38ee8956cc3e 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -1335,7 +1335,7 @@ MipsInstrInfo::findRegisterToSaveRA(const outliner::Candidate &C) const { const MipsRegisterInfo *MRI = static_cast( MF->getSubtarget().getRegisterInfo()); - for (unsigned Reg : Mips::GPR32NMRegClass) { + for (unsigned Reg : Mips::GPRNM32RegClass) { if (!MRI->isReservedReg(*MF, Reg) && Reg != Mips::RA_NM && C.LRU.available(Reg) && C.UsedInSequence.available(Reg) && diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp index b4fcb7da9bee2..b95003985ab66 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp @@ -53,7 +53,7 @@ MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF, case MipsPtrClass::Default: return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass - : ABI.IsP32() ? &Mips::GPR32NMRegClass : &Mips::GPR32RegClass; + : ABI.IsP32() ? &Mips::GPRNM32RegClass : &Mips::GPR32RegClass; case MipsPtrClass::GPR16MM: return &Mips::GPRMM16RegClass; case MipsPtrClass::StackPointer: @@ -169,7 +169,7 @@ getReservedRegs(const MachineFunction &MF) const { Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64 }; - static const MCPhysReg ReservedGPR32NM[] = { + static const MCPhysReg ReservedGPRNM32[] = { Mips::ZERO_NM, Mips::K0_NM, Mips::K1_NM, Mips::SP_NM, Mips::AT_NM }; @@ -189,8 +189,8 @@ getReservedRegs(const MachineFunction &MF) const { for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I) Reserved.set(ReservedGPR64[I]); - for (unsigned I = 0; I < array_lengthof(ReservedGPR32NM); ++I) - Reserved.set(ReservedGPR32NM[I]); + for (unsigned I = 0; I < array_lengthof(ReservedGPRNM32); ++I) + Reserved.set(ReservedGPRNM32[I]); // For mno-abicalls, GP is a program invariant! if (!Subtarget.isABICalls()) { diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index a8ffa719515d4..d0f0c34395e2d 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -340,14 +340,21 @@ class GPR32ClassNM regTypes> : let AltOrderSelect = [{ return 1; }]; } -def GPR32NM : GPR32ClassNM<[i32]>; +def GPRNM32 : GPR32ClassNM<[i32]>; // nanoMIPS "gpr3" register encoding type. -def GPR3 : +def GPRNM3 : RegisterClass<"Mips", [i32], 32, (add A0_NM, A1_NM, A2_NM, A3_NM, S0_NM, S1_NM, S2_NM, S3_NM)>; -def GPR4 : +// nanoMIPS "gpr4x4" register encoding type. +def GPRNM4 : + RegisterClass<"Mips", [i32], 32, + (add S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM, + A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM)>; + +// nanoMIPS "gpr4x4.zero" register encoding type. +def GPRNM4Zero : RegisterClass<"Mips", [i32], 32, (add A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM, S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM)>; @@ -603,17 +610,20 @@ def GPRMM16AsmOperand : MipsAsmRegOperand { let PredicateMethod = "isMM16AsmReg"; } -def GPRNM16AsmOperand : MipsAsmRegOperand { +class GPRNM32AsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNM32AsmReg"; + let PredicateMethod = "isGPRAsmReg"; +} + +class GPRNM16AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM16AsmReg"; let PredicateMethod = "isNM16AsmReg"; + let SuperClasses = Supers; } -def GPR32NMAsmOperand : MipsAsmRegOperand { - let Name = "GPR32NMAsmReg"; - let PredicateMethod = "isGPRAsmReg"; -} +def GPRNM16AsmOperand : GPRNM16AsmOperandClass; -def GPRNM4x4AsmOperand : MipsAsmRegOperand { +class GPRNM4x4AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM4x4AsmReg"; let PredicateMethod = "isNM4x4AsmReg"; } @@ -711,22 +721,21 @@ def GPR32Opnd : RegisterOperand { let ParserMatchClass = GPR32AsmOperand; } -def GPR32NMOpnd : RegisterOperand { - let ParserMatchClass = GPR32NMAsmOperand; +def GPRNM3Opnd : RegisterOperand { + let ParserMatchClass = GPRNM16AsmOperand; } -def GPR3Opnd : RegisterOperand { - let ParserMatchClass = GPRNM16AsmOperand; +def GPRNM4Opnd : RegisterOperand { + let ParserMatchClass = GPRNM4x4AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; } -def GPR4Opnd : RegisterOperand { - let ParserMatchClass = GPRNM4x4AsmOperand; +def GPRNM32Opnd : RegisterOperand { + let ParserMatchClass = GPRNM32AsmOperandClass<[GPRNM4Opnd.ParserMatchClass]>; } def GPRMM16Opnd : RegisterOperand { let ParserMatchClass = GPRMM16AsmOperand; } - def GPRMM16OpndZero : RegisterOperand { let ParserMatchClass = GPRMM16AsmOperandZero; } diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp index 56e27f7e71e94..e762e5c6dc9f5 100644 --- a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -421,7 +421,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF, const TargetRegisterClass *RC = ABI.ArePtrs64bit() ? &Mips::GPR64RegClass - : ABI.IsP32() ? &Mips::GPR32NMRegClass : &Mips::GPR32RegClass; + : ABI.IsP32() ? &Mips::GPRNM32RegClass : &Mips::GPR32RegClass; // First, compute final stack size. uint64_t StackSize = MFI.getStackSize(); @@ -724,7 +724,7 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, const TargetRegisterClass *RC = ABI.ArePtrs64bit() ? &Mips::GPR64RegClass - : ABI.IsP32() ? &Mips::GPR32NMRegClass : &Mips::GPR32RegClass; + : ABI.IsP32() ? &Mips::GPRNM32RegClass : &Mips::GPR32RegClass; // Find first instruction that restores a callee-saved register. MachineBasicBlock::iterator I = MBBI; @@ -923,7 +923,7 @@ void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF, const TargetRegisterClass &RC = ABI.ArePtrs64bit() ? Mips::GPR64RegClass - : ABI.IsP32() ? Mips::GPR32NMRegClass : Mips::GPR32RegClass; + : ABI.IsP32() ? Mips::GPRNM32RegClass : Mips::GPR32RegClass; int FI = MF.getFrameInfo().CreateStackObject(TRI->getSpillSize(RC), TRI->getSpillAlign(RC), false); RS->addScavengingFrameIndex(FI); diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp index d409046446775..ecd44487bee5a 100644 --- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp @@ -69,7 +69,7 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM, // Set up the register classes if (STI.isABI_P32()) - addRegisterClass(MVT::i32, &Mips::GPR32NMRegClass); + addRegisterClass(MVT::i32, &Mips::GPRNM32RegClass); else addRegisterClass(MVT::i32, &Mips::GPR32RegClass); diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index b20c68aed336b..2fe74e3e1d0e8 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -170,8 +170,8 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, if (Mips::MSA128BRegClass.contains(SrcReg)) Opc = Mips::MOVE_V; } - else if (Mips::GPR32NMRegClass.contains(SrcReg)) { - if (Mips::GPR32NMRegClass.contains(DestReg)) + else if (Mips::GPRNM32RegClass.contains(SrcReg)) { + if (Mips::GPRNM32RegClass.contains(DestReg)) Opc = Mips::MOVE_NM; } @@ -296,7 +296,7 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Opc = Mips::SD; else if (Mips::DSPRRegClass.hasSubClassEq(RC)) Opc = Mips::SWDSP; - else if (Mips::GPR32NMRegClass.hasSubClassEq(RC)) + else if (Mips::GPRNM32RegClass.hasSubClassEq(RC)) Opc = Mips::SW_NM; // Hi, Lo are normally caller save but they are callee save @@ -376,7 +376,7 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Opc = Mips::LD; else if (Mips::DSPRRegClass.hasSubClassEq(RC)) Opc = Mips::LWDSP; - else if (Mips::GPR32NMRegClass.hasSubClassEq(RC)) + else if (Mips::GPRNM32RegClass.hasSubClassEq(RC)) Opc = Mips::LW_NM; assert(Opc && "Register class not handled!"); @@ -657,7 +657,7 @@ unsigned MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, if (Subtarget.hasNanoMips()) { assert(Imm == (int32_t)Imm); MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); - const TargetRegisterClass *RC = &Mips::GPR32NMRegClass; + const TargetRegisterClass *RC = &Mips::GPRNM32RegClass; Register Reg = RegInfo.createVirtualRegister(RC); BuildMI(MBB, II, DL, get(Mips::Li_NM), Reg).addImm((int32_t)Imm); return Reg; diff --git a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp index b8ea753c3ed8e..71ddbec8fa8ca 100644 --- a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -255,7 +255,7 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, const TargetRegisterClass *PtrRC = ABI.ArePtrs64bit() ? &Mips::GPR64RegClass - : ABI.IsP32() ? &Mips::GPR32NMRegClass : &Mips::GPR32RegClass; + : ABI.IsP32() ? &Mips::GPRNM32RegClass : &Mips::GPR32RegClass; MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); Register Reg = RegInfo.createVirtualRegister(PtrRC); const MipsSEInstrInfo &TII = diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 5735e682851c2..53ac474b4abe2 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -674,7 +674,7 @@ class LoadUpperI32 : - ArithLogicR32_Desc { + ArithLogicR32_Desc { // Need to insert TEQ, because DIV(U)/MOD(U) don't trap on division by zero. bit usesCustomInserter = 1; } @@ -707,13 +707,13 @@ class ShiftI32_Enc psel> : _Pool_P_SHIFT { let Inst{4...0} = imm; } -class ExtBaseNM : +class ExtBaseNM : InstNM<(outs RO:$rt), (ins RO:$rs, uimm5:$pos, uimm5_plus1:$size), "ext\t$rt, $rs, $pos, $size", [(set RO:$rt, (MipsExt RO:$rs, immZExt5:$pos, immZExt5Plus1:$size))], II_EXT>; -class InsBaseNM : +class InsBaseNM : InstNM<(outs RO:$rt), (ins RO:$rs, uimm5:$pos, uimm5_inssize_plus1:$size, RO:$src), "ins \t$rt, $rs, $pos, $size", @@ -901,8 +901,8 @@ class LoadMemoryNM : - InstNM<(outs GPR32NMOpnd:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set GPR32NMOpnd:$rt, (OpNode Addr:$addr))], + InstNM<(outs GPRNM32Opnd:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set GPRNM32Opnd:$rt, (OpNode Addr:$addr))], itin> { let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; @@ -914,7 +914,7 @@ class LoadMemoryX : - InstNM<(outs GPR32NMOpnd:$rd), (ins PtrRC:$base, PtrRC:$index), + InstNM<(outs GPRNM32Opnd:$rd), (ins PtrRC:$base, PtrRC:$index), !strconcat(opstr, "\t$rd, ${index}(${base})"), [], itin> { @@ -928,7 +928,7 @@ class StoreMemoryX : - InstNM<(outs), (ins GPR32NMOpnd:$rd, PtrRC:$base, PtrRC:$index), + InstNM<(outs), (ins GPRNM32Opnd:$rd, PtrRC:$base, PtrRC:$index), !strconcat(opstr, "\t$rd, ${index}(${base})"), [], itin> { @@ -941,8 +941,8 @@ class LoadMemoryNM16 : - InstNM<(outs GPR3Opnd:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set GPR3Opnd:$rt, (OpNode Addr:$addr))], + InstNM<(outs GPRNM3Opnd:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set GPRNM3Opnd:$rt, (OpNode Addr:$addr))], itin> { let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; @@ -954,8 +954,8 @@ class StoreMemoryNM : - InstNM<(outs), (ins GPR32NMOpnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode GPR32NMOpnd:$rt, Addr:$addr)], + InstNM<(outs), (ins GPRNM32Opnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode GPRNM32Opnd:$rt, Addr:$addr)], itin> { let DecoderMethod = "DecodeMem"; let mayStore = 1; @@ -966,8 +966,8 @@ class StoreMemoryNM16 : - InstNM<(outs), (ins GPR3Opnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode GPR3Opnd:$rt, Addr:$addr)], + InstNM<(outs), (ins GPRNM3Opnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode GPRNM3Opnd:$rt, Addr:$addr)], itin> { let DecoderMethod = "DecodeMem"; let mayStore = 1; @@ -1009,8 +1009,8 @@ class CallNM, InstSize32 { let isCall = 1; let isCTI = 1; @@ -1056,13 +1056,13 @@ def RESTORE_NM : SaveRestore<"restore">, InstSize32; def RESTOREJRC_NM : SaveRestore<"restore.jrc">, InstSize32; class LoadMultipleNM : - InstNM<(outs GPR32NMOpnd:$rt), (ins mem_nms9:$addr, uimm3plus1_nm:$count), + InstNM<(outs GPRNM32Opnd:$rt), (ins mem_nms9:$addr, uimm3plus1_nm:$count), !strconcat(opstr, "\t$rt, $addr, $count"), []> { let DecoderMethod = "DecodeMem"; let mayLoad = 1; } class StoreMultipleNM : - InstNM<(outs), (ins GPR32NMOpnd:$rt, mem_nms9:$addr, uimm3plus1_nm:$count), + InstNM<(outs), (ins GPRNM32Opnd:$rt, mem_nms9:$addr, uimm3plus1_nm:$count), !strconcat(opstr, "\t$rt, $addr, $count"), []> { let DecoderMethod = "DecodeMem"; let mayStore = 1; @@ -1078,7 +1078,7 @@ class EffectiveAddressNM : } class UnalignedLoad : + RegisterOperand RO = GPRNM32Opnd> : InstNM<(outs RO:$rt), (ins mem_nms9:$addr, RO:$src), !strconcat(opstr, "\t$rt, $addr"), [(set RO:$rt, (OpNode addrsimm9:$addr, RO:$src))]> { @@ -1089,7 +1089,7 @@ class UnalignedLoad : + RegisterOperand RO = GPRNM32Opnd> : InstNM<(outs), (ins RO:$rt, mem_nms9:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RO:$rt, addrsimm9:$addr)]> { @@ -1148,41 +1148,41 @@ class LoadAddressAbsNM, +def SLLV_NM : ArithLogicR32_Desc<"sllv", GPRNM32Opnd, shl>, ArithLogicR32_Enc<0b000010>; -def SRLV_NM : ArithLogicR32_Desc<"srlv", GPR32NMOpnd, srl>, +def SRLV_NM : ArithLogicR32_Desc<"srlv", GPRNM32Opnd, srl>, ArithLogicR32_Enc<0b000110>; -def SRAV_NM : ArithLogicR32_Desc<"srav", GPR32NMOpnd, sra>, +def SRAV_NM : ArithLogicR32_Desc<"srav", GPRNM32Opnd, sra>, ArithLogicR32_Enc<0b001010>; -def ROTRV_NM : ArithLogicR32_Desc<"rotrv", GPR32NMOpnd, rotr>, +def ROTRV_NM : ArithLogicR32_Desc<"rotrv", GPRNM32Opnd, rotr>, ArithLogicR32_Enc<0b001110>; -def ADD_NM : ArithLogicR32_Desc<"add", GPR32NMOpnd>, +def ADD_NM : ArithLogicR32_Desc<"add", GPRNM32Opnd>, ArithLogicR32_Enc<0b001110>; -def ADDu_NM : ArithLogicR32_Desc<"addu", GPR32NMOpnd, add>, +def ADDu_NM : ArithLogicR32_Desc<"addu", GPRNM32Opnd, add>, ArithLogicR32_Enc<0b010110>; -def SUB_NM : ArithLogicR32_Desc<"sub", GPR32NMOpnd>, +def SUB_NM : ArithLogicR32_Desc<"sub", GPRNM32Opnd>, ArithLogicR32_Enc<0b011010>; -def SUBu_NM : ArithLogicR32_Desc<"subu", GPR32NMOpnd, sub>, +def SUBu_NM : ArithLogicR32_Desc<"subu", GPRNM32Opnd, sub>, ArithLogicR32_Enc<0b011110>; -def AND_NM : ArithLogicR32_Desc<"and", GPR32NMOpnd, and>, +def AND_NM : ArithLogicR32_Desc<"and", GPRNM32Opnd, and>, ArithLogicR32_Enc<0b100110>; -def OR_NM : ArithLogicR32_Desc<"or", GPR32NMOpnd, or>, +def OR_NM : ArithLogicR32_Desc<"or", GPRNM32Opnd, or>, ArithLogicR32_Enc<0b101010>; -def NOR_NM : ArithLogicR32_Desc<"nor", GPR32NMOpnd>, +def NOR_NM : ArithLogicR32_Desc<"nor", GPRNM32Opnd>, ArithLogicR32_Enc<0b101110>; -def XOR_NM : ArithLogicR32_Desc<"xor", GPR32NMOpnd, xor>, +def XOR_NM : ArithLogicR32_Desc<"xor", GPRNM32Opnd, xor>, ArithLogicR32_Enc<0b110010>; -def SLT_NM : ArithLogicR32_Desc<"slt", GPR32NMOpnd, setlt>, +def SLT_NM : ArithLogicR32_Desc<"slt", GPRNM32Opnd, setlt>, ArithLogicR32_Enc<0b110110>; -def SLTU_NM : ArithLogicR32_Desc<"sltu", GPR32NMOpnd, setult>, +def SLTU_NM : ArithLogicR32_Desc<"sltu", GPRNM32Opnd, setult>, ArithLogicR32_Enc<0b111010>; -def MUL_NM : ArithLogicR32_Desc<"mul", GPR32NMOpnd, mul>, +def MUL_NM : ArithLogicR32_Desc<"mul", GPRNM32Opnd, mul>, ArithLogicR32_Enc<0b000011>; -def MUH_NM : ArithLogicR32_Desc<"muh", GPR32NMOpnd, mulhs>, +def MUH_NM : ArithLogicR32_Desc<"muh", GPRNM32Opnd, mulhs>, ArithLogicR32_Enc<0b000111>; -def MULU_NM : ArithLogicR32_Desc<"mulu", GPR32NMOpnd>, +def MULU_NM : ArithLogicR32_Desc<"mulu", GPRNM32Opnd>, ArithLogicR32_Enc<0b001011>; -def MUHU_NM : ArithLogicR32_Desc<"muhu", GPR32NMOpnd, mulhu>, +def MUHU_NM : ArithLogicR32_Desc<"muhu", GPRNM32Opnd, mulhu>, ArithLogicR32_Enc<0b001111>; def DIV_NM : DivMod<"div", sdiv>, ArithLogicR32_Enc<0b010011>; @@ -1195,86 +1195,86 @@ def MODU_NM : DivMod<"modu", urem>, // 16-bit register operations let FastISelShouldIgnore = 1 in { -def ADDu16_NM : AddSubR16_Desc<"addu", GPR3Opnd, add>, +def ADDu16_NM : AddSubR16_Desc<"addu", GPRNM3Opnd, add>, AddSubR16_Enc<0b0>; -def SUBu16_NM : AddSubR16_Desc<"subu", GPR3Opnd, sub>, +def SUBu16_NM : AddSubR16_Desc<"subu", GPRNM3Opnd, sub>, AddSubR16_Enc<0b1>; -def ADDu4x4_NM : Arith4x4_Desc<"addu", GPR4Opnd, add>, +def ADDu4x4_NM : Arith4x4_Desc<"addu", GPRNM4Opnd, add>, Arith4x4_Enc<0b00>; -def MUL4x4_NM : Arith4x4_Desc<"mul", GPR4Opnd, mul>, +def MUL4x4_NM : Arith4x4_Desc<"mul", GPRNM4Opnd, mul>, Arith4x4_Enc<0b01>; } // P.U12 pool of instructions -def ORI_NM : CondLogicI32_Desc<"ori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, or>, +def ORI_NM : CondLogicI32_Desc<"ori", uimm12_nm, GPRNM32Opnd, imm32ZExt12, or>, CondLogicI32_Enc<0b0000>; -def XORI_NM : CondLogicI32_Desc<"xori", uimm12_nm, GPR32NMOpnd, imm32ZExt12, xor>, +def XORI_NM : CondLogicI32_Desc<"xori", uimm12_nm, GPRNM32Opnd, imm32ZExt12, xor>, CondLogicI32_Enc<0b0001>; -def ANDI_NM : CondLogicI32_Desc<"andi", uimm16, GPR32NMOpnd, imm32ZExt12ANDI, and>, +def ANDI_NM : CondLogicI32_Desc<"andi", uimm16, GPRNM32Opnd, imm32ZExt12ANDI, and>, CondLogicI32_Enc<0b0010>; -def SLTI_NM : CondLogicI32_Desc<"slti", uimm12_nm, GPR32NMOpnd, imm32ZExt12, setlt>, +def SLTI_NM : CondLogicI32_Desc<"slti", uimm12_nm, GPRNM32Opnd, imm32ZExt12, setlt>, CondLogicI32_Enc<0b0100>; -def SLTIU_NM : CondLogicI32_Desc<"sltiu", uimm12_nm, GPR32NMOpnd, imm32ZExt12, setult>, +def SLTIU_NM : CondLogicI32_Desc<"sltiu", uimm12_nm, GPRNM32Opnd, imm32ZExt12, setult>, CondLogicI32_Enc<0b0101>; -def SEQI_NM : CondLogicI32_Desc<"seqi", uimm12_nm, GPR32NMOpnd, imm32ZExt12, seteq>, +def SEQI_NM : CondLogicI32_Desc<"seqi", uimm12_nm, GPRNM32Opnd, imm32ZExt12, seteq>, CondLogicI32_Enc<0b0110>; // P.SHIFT pool of instructions -def SLL_NM : ShiftI32_Desc<"sll", uimm5_nm, GPR32NMOpnd, imm32ZExt5, shl>, +def SLL_NM : ShiftI32_Desc<"sll", uimm5_nm, GPRNM32Opnd, imm32ZExt5, shl>, ShiftI32_Enc<0b0000>; -def SRL_NM : ShiftI32_Desc<"srl", uimm5_nm, GPR32NMOpnd, imm32ZExt5, srl>, +def SRL_NM : ShiftI32_Desc<"srl", uimm5_nm, GPRNM32Opnd, imm32ZExt5, srl>, ShiftI32_Enc<0b0010>; -def SRA_NM : ShiftI32_Desc<"sra", uimm5_nm, GPR32NMOpnd, imm32ZExt5, sra>, +def SRA_NM : ShiftI32_Desc<"sra", uimm5_nm, GPRNM32Opnd, imm32ZExt5, sra>, ShiftI32_Enc<0b0100>; -def ROTR_NM : ShiftI32_Desc<"rotr", uimm5_nm, GPR32NMOpnd, imm32ZExt5, rotr>, +def ROTR_NM : ShiftI32_Desc<"rotr", uimm5_nm, GPRNM32Opnd, imm32ZExt5, rotr>, ShiftI32_Enc<0b0110>; def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; -def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPR32NMOpnd, +def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPRNM32Opnd, imm32SExt12OrZExt16, add>; -def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPR32NMOpnd, +def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPRNM32Opnd, imm32_NM, add>, Op48_Enc<0b00001>; -def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPR32NMOpnd, sym32_pc_nm, +def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPRNM32Opnd, sym32_pc_nm, addrpcrel>, Op48_Enc<0b00011>; -def LSA_NM : LoadScaledAddressNM<"lsa", GPR32NMOpnd>; +def LSA_NM : LoadScaledAddressNM<"lsa", GPRNM32Opnd>; -def SEB_NM : SignExtInRegNM<"seb", i8, GPR32NMOpnd>; -def SEH_NM : SignExtInRegNM<"seh", i16, GPR32NMOpnd>; +def SEB_NM : SignExtInRegNM<"seb", i8, GPRNM32Opnd>; +def SEH_NM : SignExtInRegNM<"seh", i16, GPRNM32Opnd>; -def CLZ_NM : CountLeading0NM<"clz", GPR32NMOpnd>; -def CLO_NM : CountLeading1NM<"clo", GPR32NMOpnd>; +def CLZ_NM : CountLeading0NM<"clz", GPRNM32Opnd>; +def CLO_NM : CountLeading1NM<"clo", GPRNM32Opnd>; -def BITREVW_NM : ReverseNM<"bitrevw", GPR32NMOpnd, bitreverse>; -def BYTEREVW_NM : ReverseNM<"byterevw", GPR32NMOpnd, bswap>; +def BITREVW_NM : ReverseNM<"bitrevw", GPRNM32Opnd, bitreverse>; +def BYTEREVW_NM : ReverseNM<"byterevw", GPRNM32Opnd, bswap>; // P.TRAP pool of instructions. -def TEQ_NM : Trap_Desc<"teq", GPR32NMOpnd, uimm5_nm>, Trap_Enc<0b0>; -def TNE_NM : Trap_Desc<"tne", GPR32NMOpnd, uimm5_nm>, Trap_Enc<0b1>; +def TEQ_NM : Trap_Desc<"teq", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b0>; +def TNE_NM : Trap_Desc<"tne", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b1>; -def NOT_NM : ArithLogicR16U_Desc<"not", GPR3Opnd, not>, +def NOT_NM : ArithLogicR16U_Desc<"not", GPRNM3Opnd, not>, ArithLogicR16_Enc<0b00>; -def XOR16_NM : ArithLogicR16_Desc<"xor", GPR3Opnd>, +def XOR16_NM : ArithLogicR16_Desc<"xor", GPRNM3Opnd>, ArithLogicR16_Enc<0b01>; -def AND16_NM : ArithLogicR16_Desc<"and", GPR3Opnd>, +def AND16_NM : ArithLogicR16_Desc<"and", GPRNM3Opnd>, ArithLogicR16_Enc<0b10>; -def OR16_NM : ArithLogicR16_Desc<"or ", GPR3Opnd>, +def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM3Opnd>, ArithLogicR16_Enc<0b11>; -def JRC_NM : IndirectBranchNM<"jrc", GPR32NMOpnd>; +def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>; def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { -def Li_NM : LoadAddressAbsNM<"li", GPR32NMOpnd, sym32_abs_nm, +def Li_NM : LoadAddressAbsNM<"li", GPRNM32Opnd, sym32_abs_nm, addrpcrel>, Op48_Enc<0b00000>; -def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPR32NMOpnd>, +def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPRNM32Opnd>, Op48_Enc<0b00011>; -def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPR32NMOpnd, sym32_gp_nm, +def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM32Opnd, sym32_gp_nm, addrgprel>, Op48_Enc<0b00010>; } // isReMaterializable = 1 @@ -1299,20 +1299,20 @@ class LUI_Enc isel> : _Pool_P_LUI { let Inst{0} = imm{19}; } -def LUI_NM : RegImmNM<"lui", simm32s12_nm, GPR32NMOpnd, imm32SExt20s12>, LUI_Enc<0b0>; +def LUI_NM : RegImmNM<"lui", simm32s12_nm, GPRNM32Opnd, imm32SExt20s12>, LUI_Enc<0b0>; -def ALUIPC_NM : RegImmNM<"aluipc", simm32s12_nm, GPR32NMOpnd, imm32SExt20s12>, LUI_Enc<0b1>; +def ALUIPC_NM : RegImmNM<"aluipc", simm32s12_nm, GPRNM32Opnd, imm32SExt20s12>, LUI_Enc<0b1>; -def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPR32NMOpnd>, InstSize32; +def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPRNM32Opnd>, InstSize32; -def RDHWR_NM : ReadHardwareNM; +def RDHWR_NM : ReadHardwareNM; def ADJCALLSTACKDOWN_NM : AdjustStack; def ADJCALLSTACKUP_NM : AdjustStack; // Return instruction is matched as RetRA, then expanded into PseudoReturnNM // after register allocation. Finally, MipsAsmPrinter expands this into JRC_NM. -def PseudoReturnNM : PseudoInstNM<(outs), (ins GPR32NMOpnd:$rs), []> { +def PseudoReturnNM : PseudoInstNM<(outs), (ins GPRNM32Opnd:$rs), []> { let isTerminator = 1; let isBarrier = 1; let isReturn = 1; @@ -1324,8 +1324,8 @@ def PseudoReturnNM : PseudoInstNM<(outs), (ins GPR32NMOpnd:$rs), []> { // Indirect branch is matched as PseudoIndirectBranchNM and expanded to JRC_NM. def PseudoIndirectBranchNM : - PseudoInstNM<(outs), (ins GPR32NMOpnd:$rs), [(brind GPR32NMOpnd:$rs)]>, - PseudoInstExpansion<(JRC_NM GPR32NMOpnd:$rs)> { + PseudoInstNM<(outs), (ins GPRNM32Opnd:$rs), [(brind GPRNM32Opnd:$rs)]>, + PseudoInstExpansion<(JRC_NM GPRNM32Opnd:$rs)> { let isTerminator = 1; let isBarrier = 1; let isBranch = 1; @@ -1334,12 +1334,12 @@ def PseudoIndirectBranchNM : } let hasPostISelHook = 1, isCall = 1, isCTI = 1, Defs = [RA_NM] in { - def JALRC_NM : InstNM<(outs GPR32NMOpnd:$rd), (ins GPR32NMOpnd:$rs), + def JALRC_NM : InstNM<(outs GPRNM32Opnd:$rd), (ins GPRNM32Opnd:$rs), "jalrc\t$rd, $rs", []>, InstSize32; - def JALRCPseudo : PseudoInstNM<(outs), (ins GPR32NMOpnd:$rs), - [(MipsJmpLink GPR32NMOpnd:$rs)]>, - PseudoInstExpansion<(JALRC_NM RA_NM, GPR32NMOpnd:$rs)>; + def JALRCPseudo : PseudoInstNM<(outs), (ins GPRNM32Opnd:$rs), + [(MipsJmpLink GPRNM32Opnd:$rs)]>, + PseudoInstExpansion<(JALRC_NM RA_NM, GPRNM32Opnd:$rs)>; } def : NMPat<(i32 imm32_NM:$imm), (Li_NM imm:$imm)>; @@ -1348,29 +1348,29 @@ def : NMPat<(MipsFullAddr tglobaltlsaddr:$in), (LA_NM tglobaltlsaddr:$in)>; def : NMPat<(MipsFullAddr tblockaddress:$in), (LA_NM tblockaddress:$in)>; def : NMPat<(MipsFullAddr tjumptable:$in), (LA_NM tjumptable:$in)>; -def : NMPat<(not (or GPR32NM:$rs, GPR32NM:$rt)), - (NOR_NM GPR32NM:$rs, GPR32NM:$rt)>; +def : NMPat<(not (or GPRNM32:$rs, GPRNM32:$rt)), + (NOR_NM GPRNM32:$rs, GPRNM32:$rt)>; def : NMPat<(trap), (TEQ_NM ZERO_NM, ZERO_NM, 0)>; // SetCC patterns. -def : NMPat<(setne GPR32NM:$lhs, 0), (SLTU_NM ZERO_NM, GPR32NM:$lhs)>; -def : NMPat<(seteq GPR32NM:$lhs, GPR32NM:$rhs), - (SLTIU_NM (XOR_NM GPR32NM:$lhs, GPR32NM:$rhs), 1)>; -def : NMPat<(setne GPR32NM:$lhs, GPR32NM:$rhs), - (SLTU_NM ZERO_NM, (XOR_NM GPR32NM:$lhs, GPR32NM:$rhs))>; -def : NMPat<(setle GPR32NM:$lhs, GPR32NM:$rhs), - (XORI_NM (SLT_NM GPR32NM:$rhs, GPR32NM:$lhs), 1)>; -def : NMPat<(setule GPR32NM:$lhs, GPR32NM:$rhs), - (XORI_NM (SLTU_NM GPR32NM:$rhs, GPR32NM:$lhs), 1)>; -def : NMPat<(setgt GPR32NM:$lhs, GPR32NM:$rhs), - (SLT_NM GPR32NM:$rhs, GPR32NM:$lhs)>; -def : NMPat<(setugt GPR32NM:$lhs, GPR32NM:$rhs), - (SLTU_NM GPR32NM:$rhs, GPR32NM:$lhs)>; -def : NMPat<(setge GPR32NM:$lhs, GPR32NM:$rhs), - (XORI_NM (SLT_NM GPR32NM:$lhs, GPR32NM:$rhs), 1)>; -def : NMPat<(setuge GPR32NM:$lhs, GPR32NM:$rhs), - (XORI_NM (SLTU_NM GPR32NM:$lhs, GPR32NM:$rhs), 1)>; +def : NMPat<(setne GPRNM32:$lhs, 0), (SLTU_NM ZERO_NM, GPRNM32:$lhs)>; +def : NMPat<(seteq GPRNM32:$lhs, GPRNM32:$rhs), + (SLTIU_NM (XOR_NM GPRNM32:$lhs, GPRNM32:$rhs), 1)>; +def : NMPat<(setne GPRNM32:$lhs, GPRNM32:$rhs), + (SLTU_NM ZERO_NM, (XOR_NM GPRNM32:$lhs, GPRNM32:$rhs))>; +def : NMPat<(setle GPRNM32:$lhs, GPRNM32:$rhs), + (XORI_NM (SLT_NM GPRNM32:$rhs, GPRNM32:$lhs), 1)>; +def : NMPat<(setule GPRNM32:$lhs, GPRNM32:$rhs), + (XORI_NM (SLTU_NM GPRNM32:$rhs, GPRNM32:$lhs), 1)>; +def : NMPat<(setgt GPRNM32:$lhs, GPRNM32:$rhs), + (SLT_NM GPRNM32:$rhs, GPRNM32:$lhs)>; +def : NMPat<(setugt GPRNM32:$lhs, GPRNM32:$rhs), + (SLTU_NM GPRNM32:$rhs, GPRNM32:$lhs)>; +def : NMPat<(setge GPRNM32:$lhs, GPRNM32:$rhs), + (XORI_NM (SLT_NM GPRNM32:$lhs, GPRNM32:$rhs), 1)>; +def : NMPat<(setuge GPRNM32:$lhs, GPRNM32:$rhs), + (XORI_NM (SLTU_NM GPRNM32:$lhs, GPRNM32:$rhs), 1)>; //===----------------------------------------------------------------------===// // @@ -1504,42 +1504,42 @@ def BALC16_NM : CallNM<"balc", MipsJmpLink, calltarget10_nm>, BC16_Enc<0b00110>; def : NMPat<(MipsJmpLink (i32 texternalsym:$dst)), (BALC_NM texternalsym:$dst)>; -def BEQC_NM : CBranchNM<"beqc", brtarget14_nm, seteq, GPR32NMOpnd>, +def BEQC_NM : CBranchNM<"beqc", brtarget14_nm, seteq, GPRNM32Opnd>, B14_Enc<0b000>; -def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPR32NMOpnd>, +def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPRNM32Opnd>, B14_Enc<0b010>; -def BGEUC_NM : CBranchNM<"bgeuc", brtarget14_nm, setuge, GPR32NMOpnd>, +def BGEUC_NM : CBranchNM<"bgeuc", brtarget14_nm, setuge, GPRNM32Opnd>, B14_Enc<0b011>; -def BNEC_NM : CBranchNM<"bnec", brtarget14_nm, setne, GPR32NMOpnd>, +def BNEC_NM : CBranchNM<"bnec", brtarget14_nm, setne, GPRNM32Opnd>, B14_Enc<0b100>; -def BLTC_NM : CBranchNM<"bltc", brtarget14_nm, setlt, GPR32NMOpnd>, +def BLTC_NM : CBranchNM<"bltc", brtarget14_nm, setlt, GPRNM32Opnd>, B14_Enc<0b110>; -def BLTUC_NM : CBranchNM<"bltuc", brtarget14_nm, setult, GPR32NMOpnd>, +def BLTUC_NM : CBranchNM<"bltuc", brtarget14_nm, setult, GPRNM32Opnd>, B14_Enc<0b111>; -def BEQZC_NM : CBranchZeroNM<"beqzc", brtarget7_nm, seteq, GPR32NMOpnd>, +def BEQZC_NM : CBranchZeroNM<"beqzc", brtarget7_nm, seteq, GPRNM32Opnd>, BZ16_Enc<0b10010>; -def BNEZC_NM : CBranchZeroNM<"bnezc", brtarget7_nm, setne, GPR32NMOpnd>, +def BNEZC_NM : CBranchZeroNM<"bnezc", brtarget7_nm, setne, GPRNM32Opnd>, BZ16_Enc<0b10110>; -def BEQIC_NM : CBranchImmNM<"beqic", brtarget11_nm, seteq, GPR32NMOpnd, uimm7, immZExt7>, +def BEQIC_NM : CBranchImmNM<"beqic", brtarget11_nm, seteq, GPRNM32Opnd, uimm7, immZExt7>, BRI_Enc<0b000>; -def BGEIC_NM : CBranchImmNM<"bgeic", brtarget11_nm, setge, GPR32NMOpnd, uimm7, immZExt7>, +def BGEIC_NM : CBranchImmNM<"bgeic", brtarget11_nm, setge, GPRNM32Opnd, uimm7, immZExt7>, BRI_Enc<0b010>; -def BLTIC_NM : CBranchImmNM<"bltic", brtarget11_nm, setlt, GPR32NMOpnd, uimm7, immZExt7>, +def BLTIC_NM : CBranchImmNM<"bltic", brtarget11_nm, setlt, GPRNM32Opnd, uimm7, immZExt7>, BRI_Enc<0b110>; -def BNEIC_NM : CBranchImmNM<"bneic", brtarget11_nm, setne, GPR32NMOpnd, uimm7, immZExt7>, +def BNEIC_NM : CBranchImmNM<"bneic", brtarget11_nm, setne, GPRNM32Opnd, uimm7, immZExt7>, BRI_Enc<0b100>; -def BGEIUC_NM : CBranchImmNM<"bgeiuc", brtarget11_nm, setuge, GPR32NMOpnd, uimm7, immZExt7>, +def BGEIUC_NM : CBranchImmNM<"bgeiuc", brtarget11_nm, setuge, GPRNM32Opnd, uimm7, immZExt7>, BRI_Enc<0b011>; -def BLTIUC_NM : CBranchImmNM<"bltiuc", brtarget11_nm, setult, GPR32NMOpnd, uimm7, immZExt7>, +def BLTIUC_NM : CBranchImmNM<"bltiuc", brtarget11_nm, setult, GPRNM32Opnd, uimm7, immZExt7>, BRI_Enc<0b111>; // Bit-test branches -def BBNEZC_NM : CBranchBitNM<"bbnezc", brtarget11_nm, setne, GPR32NMOpnd, simm32, simm32power2>, +def BBNEZC_NM : CBranchBitNM<"bbnezc", brtarget11_nm, setne, GPRNM32Opnd, simm32, simm32power2>, BBit_Enc<0b001>; -def BBEQZC_NM : CBranchBitNM<"bbeqzc", brtarget11_nm, seteq, GPR32NMOpnd, simm32, simm32power2>, +def BBEQZC_NM : CBranchBitNM<"bbeqzc", brtarget11_nm, seteq, GPRNM32Opnd, simm32, simm32power2>, BBit_Enc<0b101>; let isCodeGenOnly = 1, hasNoSchedulingInfo = 1, @@ -1559,9 +1559,9 @@ class TailCallBase : PseudoInstNM<(outs), (ins calltarget25_nm:$target), []>, } def TAILCALL_NM : TailCallBase; -class TailCallRegBase : PseudoInstNM<(outs), (ins GPR32NMOpnd:$rs), - [(MipsTailCall GPR32NMOpnd:$rs)]>, - PseudoInstExpansion<(JRC_NM GPR32NMOpnd:$rs)> { +class TailCallRegBase : PseudoInstNM<(outs), (ins GPRNM32Opnd:$rs), + [(MipsTailCall GPRNM32Opnd:$rs)]>, + PseudoInstExpansion<(JRC_NM GPRNM32Opnd:$rs)> { let isCall = 1; let isTerminator = 1; let isReturn = 1; @@ -1577,34 +1577,34 @@ def TAILCALLREG_NM : TailCallRegBase; // (TAILCALL_NM texternalsym:$dst)>; // '>-1' can be represented as '>=0'. -def : NMPat<(brcond (i32 (setgt GPR32NM:$lhs, -1)), bb:$dst), - (BGEC_NM GPR32NM:$lhs, ZERO_NM, bb:$dst)>; +def : NMPat<(brcond (i32 (setgt GPRNM32:$lhs, -1)), bb:$dst), + (BGEC_NM GPRNM32:$lhs, ZERO_NM, bb:$dst)>; // Reversed branch conditions: -def : NMPat<(brcond (i32 (setugt GPR32NM:$lhs, GPR32NM:$rhs)), bb:$dst), - (BLTUC_NM GPR32NM:$rhs, GPR32NM:$lhs, bb:$dst)>; -def : NMPat<(brcond (i32 (setgt GPR32NM:$lhs, GPR32NM:$rhs)), bb:$dst), - (BLTC_NM GPR32NM:$rhs, GPR32NM:$lhs, bb:$dst)>; -def : NMPat<(brcond (i32 (setule GPR32NM:$lhs, GPR32NM:$rhs)), bb:$dst), - (BGEUC_NM GPR32NM:$rhs, GPR32NM:$lhs, bb:$dst)>; -def : NMPat<(brcond (i32 (setle GPR32NM:$lhs, GPR32NM:$rhs)), bb:$dst), - (BGEC_NM GPR32NM:$rhs, GPR32NM:$lhs, bb:$dst)>; +def : NMPat<(brcond (i32 (setugt GPRNM32:$lhs, GPRNM32:$rhs)), bb:$dst), + (BLTUC_NM GPRNM32:$rhs, GPRNM32:$lhs, bb:$dst)>; +def : NMPat<(brcond (i32 (setgt GPRNM32:$lhs, GPRNM32:$rhs)), bb:$dst), + (BLTC_NM GPRNM32:$rhs, GPRNM32:$lhs, bb:$dst)>; +def : NMPat<(brcond (i32 (setule GPRNM32:$lhs, GPRNM32:$rhs)), bb:$dst), + (BGEUC_NM GPRNM32:$rhs, GPRNM32:$lhs, bb:$dst)>; +def : NMPat<(brcond (i32 (setle GPRNM32:$lhs, GPRNM32:$rhs)), bb:$dst), + (BGEC_NM GPRNM32:$rhs, GPRNM32:$lhs, bb:$dst)>; // Immediate comparison branches with offset -def : NMPat<(brcond (i32 (setgt GPR32NM:$lhs, immZExt7Plus1:$imm)), bb:$dst), - (BGEIC_NM GPR32NM:$lhs, (Plus1 $imm), bb:$dst)>; -def : NMPat<(brcond (i32 (setugt GPR32NM:$lhs, immZExt7Plus1:$imm)), bb:$dst), - (BGEIUC_NM GPR32NM:$lhs, (Plus1 $imm), bb:$dst)>; +def : NMPat<(brcond (i32 (setgt GPRNM32:$lhs, immZExt7Plus1:$imm)), bb:$dst), + (BGEIC_NM GPRNM32:$lhs, (Plus1 $imm), bb:$dst)>; +def : NMPat<(brcond (i32 (setugt GPRNM32:$lhs, immZExt7Plus1:$imm)), bb:$dst), + (BGEIUC_NM GPRNM32:$lhs, (Plus1 $imm), bb:$dst)>; // Branch on integer value -def : NMPat<(brcond (i32 GPR32NM:$lhs), bb:$dst), - (BNEC_NM GPR32NM:$lhs, ZERO_NM, bb:$dst)>; +def : NMPat<(brcond (i32 GPRNM32:$lhs), bb:$dst), + (BNEC_NM GPRNM32:$lhs, ZERO_NM, bb:$dst)>; // Bit-test branch -def : NMPat<(brcond (i32 (setne (and GPR32NM:$rt, simm32power2:$imm), 0)), bb:$offset), - (BBNEZC_NM GPR32NM:$rt, (Log2XForm $imm), bb:$offset)>; -def : NMPat<(brcond (i32 (seteq (and GPR32NM:$rt, simm32power2:$imm), 0)), bb:$offset), - (BBEQZC_NM GPR32NM:$rt, (Log2XForm $imm), bb:$offset)>; +def : NMPat<(brcond (i32 (setne (and GPRNM32:$rt, simm32power2:$imm), 0)), bb:$offset), + (BBNEZC_NM GPRNM32:$rt, (Log2XForm $imm), bb:$offset)>; +def : NMPat<(brcond (i32 (seteq (and GPRNM32:$rt, simm32power2:$imm), 0)), bb:$offset), + (BBEQZC_NM GPRNM32:$rt, (Log2XForm $imm), bb:$offset)>; //===----------------------------------------------------------------------===// @@ -1736,17 +1736,17 @@ def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000> //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; -def SWPC_NM : StorePCBase, Op48_Enc<0b01011>; -def LWPC_NM : LoadPCBase, Op48_Enc<0b01111>; +def SWPC_NM : StorePCBase, Op48_Enc<0b01011>; +def LWPC_NM : LoadPCBase, Op48_Enc<0b01111>; let isCodeGenOnly = 1 in { // TODO: Halfword load/store is never selected, this needs to be looked into. -def MOVE_NM : InstNM<(outs GPR32NMOpnd:$rt), (ins GPR32NMOpnd:$rs), +def MOVE_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), "move\t$rt, $rs", []>, InstSize16; -def MOVEP_NM : InstNM<(outs GPR32NMOpnd:$dst1, GPR32NMOpnd:$dst2), - (ins GPR32NMOpnd:$src1, GPR32NMOpnd:$src2), +def MOVEP_NM : InstNM<(outs GPRNM32Opnd:$dst1, GPRNM32Opnd:$dst2), + (ins GPRNM32Opnd:$src1, GPRNM32Opnd:$src2), "movep\t$dst1, $dst2, $src1, $src2", []>, InstSize16; } @@ -1764,42 +1764,42 @@ def MOVEP_NM : InstNM<(outs GPR32NMOpnd:$dst1, GPR32NMOpnd:$dst2), // instructions. // let AddedComplexity = 3 in { -def : NMPat<(i32 (extloadi8 (add GPR32NM:$rs, immFitsAddiu32:$imm))), - (LBU_NM (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(i32 (zextloadi8 (add GPR32NM:$rs, immFitsAddiu32:$imm))), - (LBU_NM (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(i32 (sextloadi8 (add GPR32NM:$rs, immFitsAddiu32:$imm))), - (LB_NM (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(i32 (extloadi16 (add GPR32NM:$rs, immFitsAddiu32:$imm))), - (LHU_NM (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(i32 (zextloadi16 (add GPR32NM:$rs, immFitsAddiu32:$imm))), - (LHU_NM (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(i32 (sextloadi16 (add GPR32NM:$rs, immFitsAddiu32:$imm))), - (LH_NM (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(i32 (load (add GPR32NM:$rs, immFitsAddiu32:$imm))), - (LW_NM (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(truncstorei8 GPR32NM:$rt, (add GPR32NM:$rs, immFitsAddiu32:$imm)), - (SB_NM GPR32NM:$rt, (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(truncstorei16 GPR32NM:$rt, (add GPR32NM:$rs, immFitsAddiu32:$imm)), - (SH_NM GPR32NM:$rt, (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; -def : NMPat<(store GPR32NM:$rt, (add GPR32NM:$rs, immFitsAddiu32:$imm)), - (SW_NM GPR32NM:$rt, (ADDiu_NM GPR32NM:$rs, imm:$imm), 0)>; +def : NMPat<(i32 (extloadi8 (add GPRNM32:$rs, immFitsAddiu32:$imm))), + (LBU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(i32 (zextloadi8 (add GPRNM32:$rs, immFitsAddiu32:$imm))), + (LBU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(i32 (sextloadi8 (add GPRNM32:$rs, immFitsAddiu32:$imm))), + (LB_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(i32 (extloadi16 (add GPRNM32:$rs, immFitsAddiu32:$imm))), + (LHU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(i32 (zextloadi16 (add GPRNM32:$rs, immFitsAddiu32:$imm))), + (LHU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(i32 (sextloadi16 (add GPRNM32:$rs, immFitsAddiu32:$imm))), + (LH_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(i32 (load (add GPRNM32:$rs, immFitsAddiu32:$imm))), + (LW_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(truncstorei8 GPRNM32:$rt, (add GPRNM32:$rs, immFitsAddiu32:$imm)), + (SB_NM GPRNM32:$rt, (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(truncstorei16 GPRNM32:$rt, (add GPRNM32:$rs, immFitsAddiu32:$imm)), + (SH_NM GPRNM32:$rt, (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; +def : NMPat<(store GPRNM32:$rt, (add GPRNM32:$rs, immFitsAddiu32:$imm)), + (SW_NM GPRNM32:$rt, (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; } // AddedComplexity = 3 // Catching out-of-range immediate loads/stores. -def : NMPat<(i32 (extloadi8 GPR32NM:$rs)), (LBU_NM GPR32NM:$rs, 0)>; -def : NMPat<(i32 (zextloadi8 GPR32NM:$rs)), (LBU_NM GPR32NM:$rs, 0)>; -def : NMPat<(i32 (sextloadi8 GPR32NM:$rs)), (LB_NM GPR32NM:$rs, 0)>; -def : NMPat<(i32 (extloadi16 GPR32NM:$rs)), (LHU_NM GPR32NM:$rs, 0)>; -def : NMPat<(i32 (zextloadi16 GPR32NM:$rs)), (LHU_NM GPR32NM:$rs, 0)>; -def : NMPat<(i32 (sextloadi16 GPR32NM:$rs)), (LH_NM GPR32NM:$rs, 0)>; -def : NMPat<(i32 (load GPR32NM:$rs)), (LW_NM GPR32NM:$rs, 0)>; -def : NMPat<(truncstorei8 GPR32NM:$rt, GPR32NM:$rs), - (SB_NM GPR32NM:$rt, GPR32NM:$rs, 0)>; -def : NMPat<(truncstorei16 GPR32NM:$rt, GPR32NM:$rs), - (SH_NM GPR32NM:$rt, GPR32NM:$rs, 0)>; -def : NMPat<(store GPR32NM:$rt, GPR32NM:$rs), - (SW_NM GPR32NM:$rt, GPR32NM:$rs, 0)>; +def : NMPat<(i32 (extloadi8 GPRNM32:$rs)), (LBU_NM GPRNM32:$rs, 0)>; +def : NMPat<(i32 (zextloadi8 GPRNM32:$rs)), (LBU_NM GPRNM32:$rs, 0)>; +def : NMPat<(i32 (sextloadi8 GPRNM32:$rs)), (LB_NM GPRNM32:$rs, 0)>; +def : NMPat<(i32 (extloadi16 GPRNM32:$rs)), (LHU_NM GPRNM32:$rs, 0)>; +def : NMPat<(i32 (zextloadi16 GPRNM32:$rs)), (LHU_NM GPRNM32:$rs, 0)>; +def : NMPat<(i32 (sextloadi16 GPRNM32:$rs)), (LH_NM GPRNM32:$rs, 0)>; +def : NMPat<(i32 (load GPRNM32:$rs)), (LW_NM GPRNM32:$rs, 0)>; +def : NMPat<(truncstorei8 GPRNM32:$rt, GPRNM32:$rs), + (SB_NM GPRNM32:$rt, GPRNM32:$rs, 0)>; +def : NMPat<(truncstorei16 GPRNM32:$rt, GPRNM32:$rs), + (SH_NM GPRNM32:$rt, GPRNM32:$rs, 0)>; +def : NMPat<(store GPRNM32:$rt, GPRNM32:$rs), + (SW_NM GPRNM32:$rt, GPRNM32:$rs, 0)>; // Any-extending loads def : NMPat<(i32 (extloadi8 addruimm12:$addr)), (LBU_NM addruimm12:$addr)>; @@ -1812,14 +1812,14 @@ def : NMPat<(i32 (extloadi16 addrindexedlsl1:$addr)), def : NMPat<(i32 (extloadi16 addrindexed:$addr)), (LHUX_NM addrindexed:$addr, 0)>; // Catching out-of-range immediate unaligned loads/stores. -def : NMPat<(i32 (NMUnalignedLW GPR32NM:$rs, GPR32NM:$src)), - (UALW_NM GPR32NM:$rs, 0, GPR32NM:$src)>; -def : NMPat<(NMUnalignedSW GPR32NM:$rt, GPR32NM:$rs), - (UASW_NM GPR32NM:$rt, GPR32NM:$rs, 0)>; -def : NMPat<(i32 (NMUnalignedLH GPR32NM:$rs, GPR32NM:$src)), - (UALH_NM GPR32NM:$rs, 0, GPR32NM:$src)>; -def : NMPat<(NMUnalignedSH GPR32NM:$rt, GPR32NM:$rs), - (UASH_NM GPR32NM:$rt, GPR32NM:$rs, 0)>; +def : NMPat<(i32 (NMUnalignedLW GPRNM32:$rs, GPRNM32:$src)), + (UALW_NM GPRNM32:$rs, 0, GPRNM32:$src)>; +def : NMPat<(NMUnalignedSW GPRNM32:$rt, GPRNM32:$rs), + (UASW_NM GPRNM32:$rt, GPRNM32:$rs, 0)>; +def : NMPat<(i32 (NMUnalignedLH GPRNM32:$rs, GPRNM32:$src)), + (UALH_NM GPRNM32:$rs, 0, GPRNM32:$src)>; +def : NMPat<(NMUnalignedSH GPRNM32:$rt, GPRNM32:$rs), + (UASH_NM GPRNM32:$rt, GPRNM32:$rs, 0)>; // GP-relative load. def : NMPat<(i32 (load (add GP_NM, (MipsGPRel tglobaladdr:$in)))), @@ -1854,15 +1854,15 @@ def : NMPat<(atomic_store_16 addr:$a, GPR32:$v), (SH_NM GPR32:$v, addr:$a)>; def : NMPat<(atomic_store_32 addr:$a, GPR32:$v), (SW_NM GPR32:$v, addr:$a)>; // Conditional Moves -def MOVZ_NM : InstNM<(outs GPR32NMOpnd:$rd), - (ins GPR32NMOpnd:$rs, GPR32NMOpnd:$rt, GPR32NMOpnd:$F), +def MOVZ_NM : InstNM<(outs GPRNM32Opnd:$rd), + (ins GPRNM32Opnd:$rs, GPRNM32Opnd:$rt, GPRNM32Opnd:$F), "movz\t$rd, $rs, $rt", []>, InstSize32 { let Constraints = "$F = $rd"; } -def MOVN_NM : InstNM<(outs GPR32NMOpnd:$rd), - (ins GPR32NMOpnd:$rs, GPR32NMOpnd:$rt, GPR32NMOpnd:$F), +def MOVN_NM : InstNM<(outs GPRNM32Opnd:$rd), + (ins GPRNM32Opnd:$rs, GPRNM32Opnd:$rt, GPRNM32Opnd:$F), "movn\t$rd, $rs, $rt", []>, InstSize32 { let Constraints = "$F = $rd"; @@ -1901,8 +1901,8 @@ multiclass MovzPats0NM; -defm : MovzPats1, ISA_NANOMIPS; -defm : MovzPats2NM; -defm : MovnPats, ISA_NANOMIPS; +defm : MovzPats1, ISA_NANOMIPS; +defm : MovzPats2NM; +defm : MovnPats, ISA_NANOMIPS; diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index dbdb0380cf80f..bf9f37223d493 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -45,7 +45,7 @@ struct NMLoadStoreOpt : public MachineFunctionPass { {Mips::S1_NM, 4}, {Mips::S2_NM, 5}, {Mips::S3_NM, 6}, {Mips::S4_NM, 7}, {Mips::S5_NM, 8}, {Mips::S6_NM, 9}, {Mips::S7_NM, 10}, }; - MCRegisterClass RC = MipsMCRegisterClasses[Mips::GPR32NMRegClassID]; + MCRegisterClass RC = MipsMCRegisterClasses[Mips::GPRNM32RegClassID]; NMLoadStoreOpt() : MachineFunctionPass(ID) {} StringRef getPassName() const override { return NM_LOAD_STORE_OPT_NAME; } From 76ce47507f294a905ee3058d1614b45c3d5cc023 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Thu, 22 Dec 2022 14:06:27 +0530 Subject: [PATCH 042/123] Add 32-bit non-zero register class for ADDIU[32] --- .../Mips/Disassembler/MipsDisassembler.cpp | 16 +++++++++++++ llvm/lib/Target/Mips/MipsRegisterInfo.td | 20 +++++++++++++++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 24 ++++++++++++------- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 536ff6188f327..52db766aafe3e 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -121,6 +121,11 @@ static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRNM32NZRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeGPRNM32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -1586,6 +1591,17 @@ static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPRNM32NZRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo == 0) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPRNM32NZRegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeGPRNM32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index d0f0c34395e2d..f756385b2a7ba 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -359,6 +359,14 @@ def GPRNM4Zero : (add A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM, S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM)>; +// nanoMIPS non-zero gpr register encoding type. +def GPRNM32NZ : + RegisterClass<"Mips", [i32], 32, + (add AT_NM, T4_NM, T5_NM, A0_NM, A1_NM, A2_NM, A3_NM, + A4_NM, A5_NM, A6_NM, A7_NM, T0_NM, T1_NM, T2_NM, T3_NM, + S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM, + T8_NM, T9_NM, K0_NM, K1_NM, GP_NM, SP_NM, FP_NM, RA_NM)>; + class GPR32Class regTypes> : RegisterClass<"Mips", regTypes, 32, (add // Reserved @@ -628,6 +636,12 @@ class GPRNM4x4AsmOperandClass Supers = []> : MipsAsmRegOpe let PredicateMethod = "isNM4x4AsmReg"; } +class GPRNM32NZAsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNMNonZeroAsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; + let PredicateMethod = "isGPRNonZeroAsmReg"; +} + def GPRMM16AsmOperandZero : MipsAsmRegOperand { let Name = "GPRMM16AsmRegZero"; let PredicateMethod = "isMM16AsmRegZero"; @@ -729,8 +743,12 @@ def GPRNM4Opnd : RegisterOperand { let ParserMatchClass = GPRNM4x4AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; } +def GPRNM32NZOpnd : RegisterOperand { + let ParserMatchClass = GPRNM32NZAsmOperandClass<[GPRNM4Opnd.ParserMatchClass]>; +} + def GPRNM32Opnd : RegisterOperand { - let ParserMatchClass = GPRNM32AsmOperandClass<[GPRNM4Opnd.ParserMatchClass]>; + let ParserMatchClass = GPRNM32AsmOperandClass<[GPRNM32NZOpnd.ParserMatchClass]>; } def GPRMM16Opnd : RegisterOperand { diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 53ac474b4abe2..b1d2b8998722a 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -571,7 +571,6 @@ class Arith4x4_Desc { - let Constraints = "$rt = $dst"; Format Form = FrmR; } @@ -634,25 +633,32 @@ class AddSubR16_Enc isel>: _Pool_P16_ADDU { let Inst{0} = 0; } +class ArithLogicINM2Reg : + InstNM<(outs DRO:$rt), (ins SRO:$rs, Od:$imm), + !strconcat(opstr, "\t$rt, $rs, $imm"), + [(set DRO:$rt, (OpNode SRO:$rs, imm_type:$imm))]> { + let isReMaterializable = 1; +} + // Arithmetic and logical instructions with 2 register operands and immediate. class ArithLogicINM : - InstNM<(outs RO:$rt), (ins RO:$rs, Od:$imm), - !strconcat(opstr, "\t$rt, $rs, $imm"), - [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm))]> { - let isReMaterializable = 1; -} + ArithLogicINM2Reg; class ArithLogicI32 : ArithLogicINM; -class AddiU32 : - ArithLogicINM, _Pool_P32<0b00000> { + ArithLogicINM2Reg, _Pool_P32<0b00000> { bits<5> rt; bits<5> rs; bits<16> imm; @@ -1232,7 +1238,7 @@ def ROTR_NM : ShiftI32_Desc<"rotr", uimm5_nm, GPRNM32Opnd, imm32ZExt5, rotr>, def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; -def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPRNM32Opnd, +def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPRNM32NZOpnd, GPRNM32Opnd, imm32SExt12OrZExt16, add>; def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPRNM32Opnd, imm32_NM, add>, Op48_Enc<0b00001>; From 73d58ef3ad36a3e0a737d483e1f5cbc5df5297a9 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 27 Dec 2022 10:49:17 +0530 Subject: [PATCH 043/123] Fix 4x4 register decoding classes and methods --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 11 +++++----- .../Mips/Disassembler/MipsDisassembler.cpp | 16 +++++++++----- llvm/lib/Target/Mips/MipsRegisterInfo.td | 9 ++++---- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 22 +++++++++++++------ 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 46fe7576f27d6..43b1be3fca247 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -936,13 +936,12 @@ class MipsOperand : public MCParsedAsmOperand { /// Coerce the register to GPR32 and return the real register for the current /// target. - unsigned getGPRNM16Reg() const { + unsigned getGPRNM32Reg() const { assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); - unsigned ClassID = Mips::GPR32RegClassID; + unsigned ClassID = Mips::GPRNM32RegClassID; return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); } - /// Coerce the register to GPR64 and return the real register for the current /// target. unsigned getGPR64Reg() const { @@ -1108,17 +1107,17 @@ class MipsOperand : public MCParsedAsmOperand { void addGPRNM32AsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - addGPR32AsmRegOperands(Inst, N); + Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); } void addGPRNM16AsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createReg(getGPR32Reg())); + Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); } void addGPRNM4x4AsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createReg(getGPR32Reg())); + Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); } void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const { diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 52db766aafe3e..d9146cd0bbaa4 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1293,7 +1293,7 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, LLVM_DEBUG( dbgs() << "Trying NanoMips16 table (16-bit instructions):\n"); - // Calling the auto-generated decoder function for microMIPS32R6 + // Calling the auto-generated decoder function for NanoMips // 16-bit instructions. Result = decodeInstruction(DecoderTableNanoMips16, Instr, Insn, Address, this, STI); @@ -1575,7 +1575,8 @@ static DecodeStatus DecodeGPRNM3RegisterClass(MCInst &Inst, const void *Decoder) { if (RegNo > 7) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::GPRNM3RegClassID, RegNo); + RegNo |= ((RegNo & 0x4) ^ 0x4) << 2; + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1584,9 +1585,10 @@ static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - if (RegNo > 15) + if (RegNo > 31) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::GPRNM4RegClassID, RegNo); + RegNo += (RegNo < 4 ? 8 : 0); + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } @@ -1606,7 +1608,11 @@ static DecodeStatus DecodeGPRNM32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); + if (RegNo > 31) + return MCDisassembler::Fail; + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; } static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index f756385b2a7ba..9ad273a8a4c4f 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -345,13 +345,13 @@ def GPRNM32 : GPR32ClassNM<[i32]>; // nanoMIPS "gpr3" register encoding type. def GPRNM3 : RegisterClass<"Mips", [i32], 32, - (add A0_NM, A1_NM, A2_NM, A3_NM, S0_NM, S1_NM, S2_NM, S3_NM)>; + (add S0_NM, S1_NM, S2_NM, S3_NM, A0_NM, A1_NM, A2_NM, A3_NM)>; // nanoMIPS "gpr4x4" register encoding type. def GPRNM4 : RegisterClass<"Mips", [i32], 32, - (add S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM, - A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM)>; + (add A4_NM, A5_NM, A6_NM, A7_NM, A0_NM, A1_NM, A2_NM, A3_NM, + S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM)>; // nanoMIPS "gpr4x4.zero" register encoding type. def GPRNM4Zero : @@ -362,7 +362,7 @@ def GPRNM4Zero : // nanoMIPS non-zero gpr register encoding type. def GPRNM32NZ : RegisterClass<"Mips", [i32], 32, - (add AT_NM, T4_NM, T5_NM, A0_NM, A1_NM, A2_NM, A3_NM, + (add AT_NM, T4_NM, T5_NM, A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM, T0_NM, T1_NM, T2_NM, T3_NM, S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM, T8_NM, T9_NM, K0_NM, K1_NM, GP_NM, SP_NM, FP_NM, RA_NM)>; @@ -633,6 +633,7 @@ def GPRNM16AsmOperand : GPRNM16AsmOperandClass; class GPRNM4x4AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM4x4AsmReg"; + let RenderMethod = "addGPRNM4x4AsmRegOperands"; let PredicateMethod = "isNM4x4AsmReg"; } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index b1d2b8998722a..d861c328e5a85 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -568,13 +568,21 @@ class _Pool_PP_LSX isel> : _Pool_POOL32A7<0b000> { // 16-bit arithmetic and logical instructions with 4x4 register operands, P16_4X4 class Arith4x4_Desc: - InstNM<(outs RO:$dst), (ins RO:$rs, RO:$rt), - !strconcat(opstr, "\t$dst, $rs, $rt"), - [(set RO:$dst, (OpNode RO:$rs, RO:$rt))]> { + InstNM<(outs RO:$dst), (ins RO:$rt, RO:$rs), + !strconcat(opstr, "\t$dst, $rt, $rs"), + [(set RO:$dst, (OpNode RO:$rt, RO:$rs))]> { Format Form = FrmR; } -class Arith4x4_Enc isel>: _Pool_P16_4X4; +class Arith4x4_Enc isel>: _Pool_P16_4X4 { + bits<5> dst; + bits<5> rs; + + let Inst{9} = dst{4}; + let Inst{7...5} = dst{2...0}; + let Inst{4} = rs{4}; + let Inst{2...0} = rs{2...0}; +} // 32-bit arithmetic and logical instructions with 3 register operands. @@ -1200,11 +1208,11 @@ def MODU_NM : DivMod<"modu", urem>, ArithLogicR32_Enc<0b011111>; // 16-bit register operations -let FastISelShouldIgnore = 1 in { -def ADDu16_NM : AddSubR16_Desc<"addu", GPRNM3Opnd, add>, - AddSubR16_Enc<0b0>; +let FastISelShouldIgnore = 1, isCommutable=1 in { def SUBu16_NM : AddSubR16_Desc<"subu", GPRNM3Opnd, sub>, AddSubR16_Enc<0b1>; +def ADDu16_NM : AddSubR16_Desc<"addu", GPRNM3Opnd, add>, + AddSubR16_Enc<0b0>; def ADDu4x4_NM : Arith4x4_Desc<"addu", GPRNM4Opnd, add>, Arith4x4_Enc<0b00>; def MUL4x4_NM : Arith4x4_Desc<"mul", GPRNM4Opnd, mul>, From c240ff47449dd735cd2333260f4dda735597190b Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 27 Dec 2022 14:11:12 +0530 Subject: [PATCH 044/123] Fix encoding collisions --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index d861c328e5a85..91ac28046c067 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -638,7 +638,6 @@ class AddSubR16_Enc isel>: _Pool_P16_ADDU { let Inst{9...7} = rt; let Inst{6...4} = rs; let Inst{3...1} = rd; - let Inst{0} = 0; } class ArithLogicINM2Reg, def ROTRV_NM : ArithLogicR32_Desc<"rotrv", GPRNM32Opnd, rotr>, ArithLogicR32_Enc<0b001110>; def ADD_NM : ArithLogicR32_Desc<"add", GPRNM32Opnd>, - ArithLogicR32_Enc<0b001110>; + ArithLogicR32_Enc<0b010010>; def ADDu_NM : ArithLogicR32_Desc<"addu", GPRNM32Opnd, add>, ArithLogicR32_Enc<0b010110>; def SUB_NM : ArithLogicR32_Desc<"sub", GPRNM32Opnd>, @@ -1285,14 +1284,14 @@ def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { def Li_NM : LoadAddressAbsNM<"li", GPRNM32Opnd, sym32_abs_nm, addrpcrel>, Op48_Enc<0b00000>; -def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPRNM32Opnd>, - Op48_Enc<0b00011>; - def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM32Opnd, sym32_gp_nm, addrgprel>, Op48_Enc<0b00010>; - } // isReMaterializable = 1 +let isReMaterializable = 1,isCodeGenOnly = 1 in { +def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPRNM32Opnd>, + Op48_Enc<0b00011>; +} // Arithmetic and logical instructions with 2 register operands and immediate. class LoadUpperINM, def LBU16_NM : LoadMemoryNM16<"lbu", mem_nm2, zextloadi8, addruimm2, II_LB>, LBMem16_Enc<0b10>; def SB16_NM : StoreMemoryNM16<"sb", mem_nm2, truncstorei8, addruimm2, II_SB>, - LHMem16_Enc<0b01>; + LBMem16_Enc<0b01>; def LWGP_NM : LoadMemoryNM<"lw", mem_nm_gp19s2, load, addrgp19s2, II_LW>, LSMemGP19S2_Enc<0b10>; @@ -1725,7 +1724,7 @@ def SWX_NM : StoreMemoryX<"swx", mem_nmrx, store, addrindexed, II_SW>, def LBUX_NM : LoadMemoryX<"lbux", mem_nmrx, zextloadi8, addrindexed, II_LBU>, LSMemX_Enc<0, 0b0010>; def LHUX_NM : LoadMemoryX<"lhux", mem_nmrx, zextloadi16, addrindexed, II_LHU>, - LSMemX_Enc<0, 0b0000>; + LSMemX_Enc<0, 0b0110>; def LHXS_NM : LoadMemoryX<"lhxs", mem_nmrx, sextloadi16, addrindexedlsl1, II_LH>, LSMemX_Enc<0b1, 0b0100>; From 075e7797501ed6d7303518d9472c5c458872ae83 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Wed, 28 Dec 2022 11:18:25 +0530 Subject: [PATCH 045/123] Add 3-bit nanoMIPS register set including zero --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 35 +++++++++++-------- llvm/lib/Target/Mips/MipsRegisterInfo.td | 24 +++++++++++-- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 8 ++--- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 43b1be3fca247..a9bef16bf4ac2 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1105,21 +1105,6 @@ class MipsOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); } - void addGPRNM32AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); - } - - void addGPRNM16AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); - } - - void addGPRNM4x4AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); - } - void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); @@ -1141,6 +1126,11 @@ class MipsOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); } + void addGPRNM32AsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); + } + /// Render the operand to an MCInst as a GPR64 /// Asserts if the wrong number of operands are requested, or the operand /// is not a k_RegisterIndex compatible with RegKind_GPR @@ -1839,6 +1829,15 @@ class MipsOperand : public MCParsedAsmOperand { } + bool isNM16ZeroAsmReg() const { + if (!(isRegIdx() && RegIdx.Kind)) + return false; + volatile unsigned RegNo = RegIdx.Index; + return ((RegNo == 0) || + (RegNo >= 5 && RegNo <= 7) || + (RegNo >= 17 && RegNo <= 19)); + } + bool isNM4x4AsmReg() const { if (!(isRegIdx() && RegIdx.Kind)) return false; @@ -1847,6 +1846,12 @@ class MipsOperand : public MCParsedAsmOperand { } + bool isGPRNMAsmReg() const { + if (!(isRegIdx() && RegIdx.Kind)) + return false; + return (RegIdx.Index < 32); + } + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const override { return StartLoc; } /// getEndLoc - Get the location of the last token of this operand. diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index 9ad273a8a4c4f..3c0af7e9c787a 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -347,6 +347,11 @@ def GPRNM3 : RegisterClass<"Mips", [i32], 32, (add S0_NM, S1_NM, S2_NM, S3_NM, A0_NM, A1_NM, A2_NM, A3_NM)>; +// nanoMIPS "gpr3" register encoding type. +def GPRNM3Z : + RegisterClass<"Mips", [i32], 32, + (add ZERO_NM, S1_NM, S2_NM, S3_NM, A0_NM, A1_NM, A2_NM, A3_NM)>; + // nanoMIPS "gpr4x4" register encoding type. def GPRNM4 : RegisterClass<"Mips", [i32], 32, @@ -620,20 +625,31 @@ def GPRMM16AsmOperand : MipsAsmRegOperand { class GPRNM32AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM32AsmReg"; - let PredicateMethod = "isGPRAsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; } class GPRNM16AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM16AsmReg"; let PredicateMethod = "isNM16AsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; let SuperClasses = Supers; } def GPRNM16AsmOperand : GPRNM16AsmOperandClass; +class GPRNM16ZeroAsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNM16ZAsmReg"; + let PredicateMethod = "isNM16ZeroAsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; + let SuperClasses = Supers; +} + +def GPRNM16ZeroAsmOperand : GPRNM16ZeroAsmOperandClass; + class GPRNM4x4AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM4x4AsmReg"; - let RenderMethod = "addGPRNM4x4AsmRegOperands"; + let RenderMethod = "addGPRNM32AsmRegOperands"; let PredicateMethod = "isNM4x4AsmReg"; } @@ -740,6 +756,10 @@ def GPRNM3Opnd : RegisterOperand { let ParserMatchClass = GPRNM16AsmOperand; } +def GPRNM3ZOpnd : RegisterOperand { + let ParserMatchClass = GPRNM16ZeroAsmOperand; +} + def GPRNM4Opnd : RegisterOperand { let ParserMatchClass = GPRNM4x4AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 91ac28046c067..5c6530d4fe958 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -979,8 +979,8 @@ class StoreMemoryNM16 : - InstNM<(outs), (ins GPRNM3Opnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode GPRNM3Opnd:$rt, Addr:$addr)], + InstNM<(outs), (ins GPRNM3ZOpnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode GPRNM3ZOpnd:$rt, Addr:$addr)], itin> { let DecoderMethod = "DecodeMem"; let mayStore = 1; @@ -1626,9 +1626,9 @@ def : NMPat<(brcond (i32 (seteq (and GPRNM32:$rt, simm32power2:$imm), 0)), bb:$o // //===----------------------------------------------------------------------===// def LWSP16_NM : LoadMemoryNM16<"lw", mem_nm_sp5s2, load, addrsp5s2, II_LW>, - LSSPRegMem16_Enc<0b00101>; + LSSPRegMem16_Enc<0b00101>; // Broken def SWSP16_NM : StoreMemoryNM16<"sw", mem_nm_sp5s2, store, addrsp5s2, II_SW>, - LSSPRegMem16_Enc<0b10101>; + LSSPRegMem16_Enc<0b10101>; // Broken def LWGP16_NM : LoadMemoryNM16<"lw", mem_nm_gp7s2, load, addrgp7s2, II_LW>, LSGPRegMem16_Enc<0b01001>; def SWGP16_NM : StoreMemoryNM16<"sw", mem_nm_gp7s2, store, addrgp7s2, II_SW>, From dbb0e2a9f5c153cc44c358e41b082de38a050d89 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 30 Dec 2022 11:07:01 +0530 Subject: [PATCH 046/123] Fix load/store operands - base registers and offset ranges --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 82 ++++++++- .../Mips/Disassembler/MipsDisassembler.cpp | 80 +++++++++ llvm/lib/Target/Mips/MipsRegisterInfo.td | 44 ++++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 167 +++++++++++------- 4 files changed, 295 insertions(+), 78 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index a9bef16bf4ac2..7e2f01745312a 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1313,6 +1313,15 @@ class MipsOperand : public MCParsedAsmOperand { addExpr(Inst, Expr); } + void addNMMemOperands(MCInst &Inst, unsigned N) const { + assert(N == 2 && "Invalid number of operands!"); + + Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRNM32Reg())); + + const MCExpr *Expr = getMemOff(); + addExpr(Inst, Expr); + } + void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); @@ -1410,6 +1419,34 @@ class MipsOperand : public MCParsedAsmOperand { return IsReloc && isShiftedUInt(Res.getConstant()); } + template + bool isMemWithBaseUimmOffset() const { + MCValue Res; + if (!isMem()) + return false; + if (!getMemBase()->isGPRAsmReg() + || !MipsMCRegisterClasses[ClassID].contains(getMemBase()->getGPRNM32Reg())) + return false; + if (isConstantMemOff()) + return isShiftedUInt(getConstantMemOff()); + return getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + } + + template + bool isMemWithBaseSimmOffset() const { + MCValue Res; + if (!isMem()) + return false; + if (!getMemBase()->isGPRAsmReg() + || !MipsMCRegisterClasses[ClassID].contains(getMemBase()->getGPRNM32Reg())) + return false; + if (isConstantMemOff()) + return isShiftedUInt(getConstantMemOff()); + return getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + } + bool isMemRx() const { if (!isMem()) return false; @@ -1490,8 +1527,12 @@ class MipsOperand : public MCParsedAsmOperand { MCValue Res; bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); - return (IsReloc || (isConstantMemOff() && isUInt(getConstantMemOff()) - && (getConstantMemOff() % Align == 0))); + + if (isConstantMemOff()) + return (isUInt(getConstantMemOff()) && + (getConstantMemOff() % Align == 0)); + else + return IsReloc; } return false; } @@ -1846,10 +1887,45 @@ class MipsOperand : public MCParsedAsmOperand { } + bool isNM4x4ZeroAsmReg() const { + if (!(isRegIdx() && RegIdx.Kind)) + return false; + return ((RegIdx.Index == 0) || + (RegIdx.Index >= 4 && RegIdx.Index <= 10) || + (RegIdx.Index >= 16 && RegIdx.Index <= 23)); + } + + enum NM_REG_TYPE { + NMR, + NMR_NZ, + NMR_3, + NMR_3Z, + NMR_4, + NMR_4Z + }; + + template bool isGPRNMAsmReg() const { if (!(isRegIdx() && RegIdx.Kind)) return false; - return (RegIdx.Index < 32); + switch (rt) { + case Mips::GPRNMGPRegClassID: + return (RegIdx.Index == 28); + case Mips::GPRNMSPRegClassID: + return (RegIdx.Index == 29); + case Mips::GPRNM32NZRegClassID: + return (RegIdx.Index > 0 && RegIdx.Index < 32); + case Mips::GPRNM3RegClassID: + return isNM16AsmReg(); + case Mips::GPRNM3ZRegClassID: + return isNM16ZeroAsmReg(); + case Mips::GPRNM4RegClassID: + return isNM4x4AsmReg(); + case Mips::GPRNM4ZeroRegClassID: + return isNM4x4ZeroAsmReg(); + default: + return (RegIdx.Index < 32); + } } /// getStartLoc - Get the location of the first token of this operand. diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index d9146cd0bbaa4..73e92b7abd56f 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -121,6 +121,16 @@ static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRNM3ZRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeGPRNM4ZRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeGPRNM32NZRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -314,6 +324,12 @@ static DecodeStatus DecodeMem(MCInst &Inst, uint64_t Address, const void *Decoder); +template +static DecodeStatus DecodeMemNM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1581,6 +1597,19 @@ static DecodeStatus DecodeGPRNM3RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPRNM3ZRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 7) + return MCDisassembler::Fail; + if (RegNo != 0) + RegNo |= ((RegNo & 0x4) ^ 0x4) << 2; + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -1593,6 +1622,21 @@ static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPRNM4ZRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + if (RegNo == 3) + RegNo = 0; + else + RegNo += (RegNo < 3 ? 8 : 0); + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeGPRNM32NZRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -1711,6 +1755,41 @@ static DecodeStatus DecodeMem(MCInst &Inst, return MCDisassembler::Success; } +template +static DecodeStatus DecodeMemNM(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = (Insn & ((1 << Offbits) - 1)); + if (isSigned) + Offset = SignExtend32(Offset); + unsigned Base; + + switch (rt) { + case Mips::GPRNMGPRegClassID: + case Mips::GPRNMSPRegClassID: + Base = 0; + break; + case Mips::GPRNM3RegClassID: + Base = fieldFromInstruction(Insn, Offbits, 3); + break; + default: + Base = fieldFromInstruction(Insn, Offbits, 5); + } + Base = getReg(Decoder, rt, Base); + +// if (Inst.getOpcode() == Mips::SC || +// Inst.getOpcode() == Mips::SCD) +// Inst.addOperand(MCOperand::createReg(Reg)); + + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + + return MCDisassembler::Success; +} + + static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -2096,6 +2175,7 @@ static DecodeStatus DecodeMemMMImm16(MCInst &Inst, return MCDisassembler::Success; } + static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index 3c0af7e9c787a..de526d5991c95 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -372,6 +372,10 @@ def GPRNM32NZ : S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM, T8_NM, T9_NM, K0_NM, K1_NM, GP_NM, SP_NM, FP_NM, RA_NM)>; +def GPRNMSP : RegisterClass<"Mips", [i32], 32, (add SP_NM)>; + +def GPRNMGP : RegisterClass<"Mips", [i32], 32, (add GP_NM)>; + class GPR32Class regTypes> : RegisterClass<"Mips", regTypes, 32, (add // Reserved @@ -631,32 +635,46 @@ class GPRNM32AsmOperandClass Supers = []> : MipsAsmRegOper class GPRNM16AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM16AsmReg"; - let PredicateMethod = "isNM16AsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; let RenderMethod = "addGPRNM32AsmRegOperands"; let SuperClasses = Supers; } -def GPRNM16AsmOperand : GPRNM16AsmOperandClass; +class GPRNMSPAsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNMSPAsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; + let SuperClasses = Supers; +} + +class GPRNMGPAsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNMGPAsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; + let SuperClasses = Supers; +} + +def GPRNMGPAsmOperand : GPRNMGPAsmOperandClass; class GPRNM16ZeroAsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM16ZAsmReg"; - let PredicateMethod = "isNM16ZeroAsmReg"; + let Name = "GPRNM16ZeroAsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; let RenderMethod = "addGPRNM32AsmRegOperands"; let SuperClasses = Supers; } -def GPRNM16ZeroAsmOperand : GPRNM16ZeroAsmOperandClass; +//def GPRNM16ZeroAsmOperand : GPRNM16ZeroAsmOperandClass; class GPRNM4x4AsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNM4x4AsmReg"; let RenderMethod = "addGPRNM32AsmRegOperands"; - let PredicateMethod = "isNM4x4AsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; } class GPRNM32NZAsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNMNonZeroAsmReg"; let RenderMethod = "addGPRNM32AsmRegOperands"; - let PredicateMethod = "isGPRNonZeroAsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; } def GPRMM16AsmOperandZero : MipsAsmRegOperand { @@ -752,12 +770,20 @@ def GPR32Opnd : RegisterOperand { let ParserMatchClass = GPR32AsmOperand; } +def GPRNMGPOpnd : RegisterOperand { + let ParserMatchClass = GPRNMGPAsmOperand; +} + +def GPRNMSPOpnd : RegisterOperand { + let ParserMatchClass = GPRNMSPAsmOperandClass<[GPRNMGPOpnd.ParserMatchClass]>; +} + def GPRNM3Opnd : RegisterOperand { - let ParserMatchClass = GPRNM16AsmOperand; + let ParserMatchClass = GPRNM16AsmOperandClass<[GPRNMSPOpnd.ParserMatchClass]>; } def GPRNM3ZOpnd : RegisterOperand { - let ParserMatchClass = GPRNM16ZeroAsmOperand; + let ParserMatchClass = GPRNM16ZeroAsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; } def GPRNM4Opnd : RegisterOperand { diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 5c6530d4fe958..af12b17a9b12e 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -103,20 +103,28 @@ def SymAsmOperandGPRel : SymAsmOperandClass<"GPRel">; def SImm32S12AsmOperandClass : SImmScaledAsmOperandClass<20, 12, []>; -class NMMemGPAsmOperand Supers = [MipsMemAsmOperand]> - : MipsMemSimmAsmOperand { - let Name = "NMMemGP" # Bits # "s" # Align; - let RenderMethod = "addMemOperands"; +class NMMemUimmAsmOperand Supers = [MipsMemAsmOperand]> : AsmOperandClass { + let Name = "NMMemOffsetUimm" # Width # "_" # Shift; + let SuperClasses = Supers; + let RenderMethod = "addNMMemOperands"; let ParserMethod = "parseMemOperand"; - let SuperClasses = Supers; - let PredicateMethod = "isMemWithUimmOffsetGP<" # Bits # "," # Align # ">"; + let PredicateMethod = "isMemWithBaseUimmOffset<" # Width # ", " # Shift # ", " # RegClass # ">"; + let DiagnosticType = !if(!eq(Shift, 0), "MemUImm" # Width, + "MemUImm" # Width # "Lsl" # Shift); } -class NMMemSPAsmOperand - : AsmOperandClass { - let Name = "NMMemSP" # Bits # "s" # Align; - let RenderMethod = "addMemOperands"; - let PredicateMethod = "isMemWithUimmOffsetSP<" # Bits # "," # Align # ">"; +class NMMemSimmAsmOperand Supers = [MipsMemAsmOperand]> : AsmOperandClass { + let Name = "NMMemOffsetSimm" # Width # "_" # Shift; + let SuperClasses = Supers; + let RenderMethod = "addNMMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithBaseSimmOffset<" # Width # ", " # Shift # ", " # RegClass # ">"; + let DiagnosticType = !if(!eq(Shift, 0), "MemUImm" # Width, + "MemUImm" # Width # "Lsl" # Shift); } def NMJumpTargetAsmOperand : AsmOperandClass { @@ -147,74 +155,103 @@ def uimm16_nm : Operand { let ParserMatchClass = !cast("SImm16AsmOperandClass"); } -def mem_nms9 : mem_generic { - let EncoderMethod = "getMemEncodingNMImm9"; - let ParserMatchClass = MipsMemSimmAsmOperand<9>; -} +def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; -def mem_nmu12 : mem_generic { - let EncoderMethod = "getMemEncodingNMImm12"; - let ParserMatchClass = MipsMemUimmAsmOperand<12>; +def mem_nm_gp7s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let DecoderMethod = "DecodeMemNM<9,false,Mips::GPRNMGPRegClassID>"; + let OperandType = "OPERAND_NM_GPREL9"; + let OperandNamespace = "NanoMips"; + let ParserMatchClass = MemNMGP7S2Parser; } -def mem_nmpcrel : mem_generic { - let EncoderMethod = "getMemEncodingNMImm9"; - let ParserMatchClass = MipsMemSimmAsmOperand<9>; -} +def MemNMSP5S2Parser : + NMMemUimmAsmOperand<5,2,"Mips::GPRNMSPRegClassID",[MemNMGP7S2Parser]>; -def mem_nmrx : mem_generic { - let EncoderMethod = "getMemEncodingNMRX"; - let ParserMatchClass = MipsMemRxAsmOperand; +def mem_nm_sp5s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMSP"; + let DecoderMethod = "DecodeMemNM<7,false,Mips::GPRNMSPRegClassID>"; + let OperandType = "OPERAND_NM_SPREL7"; + let OperandNamespace = "NanoMips"; + let ParserMatchClass = MemNMSP5S2Parser; } +def MemNM6S2Parser : + NMMemUimmAsmOperand<4,2,"Mips::GPRNM3RegClassID",[MemNMSP5S2Parser]>; +def MemNM3S1Parser : + NMMemUimmAsmOperand<3,1,"Mips::GPRNM3RegClassID",[MemNMSP5S2Parser]>; +def MemNM2Parser : + NMMemUimmAsmOperand<2,0,"Mips::GPRNM3RegClassID",[MemNMSP5S2Parser]>; + def mem_nm6s2 : mem_generic { let EncoderMethod = "getMemEncodingNMImm6S2"; - let ParserMatchClass = MipsMemUimmAsmOperand<4,2>; + let DecoderMethod = "DecodeMemNM<6,false,Mips::GPRNM3RegClassID>"; + let ParserMatchClass = MemNM6S2Parser; } def mem_nm3s1 : mem_generic { let EncoderMethod = "getMemEncodingNMImm3S1"; - let ParserMatchClass = MipsMemUimmAsmOperand<2,1>; + let ParserMatchClass = MemNM3S1Parser; } def mem_nm2 : mem_generic { let EncoderMethod = "getMemEncodingNMImm2"; - let ParserMatchClass = MipsMemUimmAsmOperand<2>; + let ParserMatchClass = MemNM2Parser; } +def MemNMGP19S2Parser : NMMemUimmAsmOperand<19,2, + "Mips::GPRNMGPRegClassID",[MemNMGP7S2Parser]>; + def mem_nm_gp19s2 : mem_generic { let EncoderMethod = "getMemEncodingNMGP"; - let ParserMatchClass = NMMemGPAsmOperand<21,4>; - let OperandNamespace = "NanoMips"; let OperandType = "OPERAND_NM_GPREL21"; + let OperandNamespace = "NanoMips"; + let DecoderMethod = "DecodeMemNM<21,false,Mips::GPRNMGPRegClassID>"; + let ParserMatchClass = MemNMGP7S2Parser; } def mem_nm_gp18 : mem_generic { let EncoderMethod = "getMemEncodingNMGP"; - let ParserMatchClass = NMMemGPAsmOperand<18,1>; - let OperandNamespace = "NanoMips"; + let DecoderMethod = "DecodeMemNM<18,false,Mips::GPRNMGPRegClassID>"; let OperandType = "OPERAND_NM_GPREL18"; + let OperandNamespace = "NanoMips"; + let ParserMatchClass = NMMemUimmAsmOperand<18,0,"Mips::GPRNMGPRegClassID",[MemNMGP7S2Parser]>; } def mem_nm_gp17s1 : mem_generic { let EncoderMethod = "getMemEncodingNMGP"; - let ParserMatchClass = NMMemGPAsmOperand<18,2>; - let OperandNamespace = "NanoMips"; + let DecoderMethod = "DecodeMemNM<18,false,Mips::GPRNMGPRegClassID>"; let OperandType = "OPERAND_NM_GPREL18"; + let OperandNamespace = "NanoMips"; + let ParserMatchClass = NMMemUimmAsmOperand<17,1,"Mips::GPRNMGPRegClassID",[MemNMGP7S2Parser]>; } -def mem_nm_gp7s2 : mem_generic { - let EncoderMethod = "getMemEncodingNMGP"; - let ParserMatchClass = NMMemGPAsmOperand<9,4>; - let OperandNamespace = "NanoMips"; - let OperandType = "OPERAND_NM_GPREL9"; +def MemNMU12Parser : NMMemUimmAsmOperand<12,0, + "Mips::GPRNM32RegClassID",[MemNMGP19S2Parser]>; + +def mem_nmu12 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm12"; + let DecoderMethod = "DecodeMemNM<12,false,Mips::GPRNM32RegClassID>"; + let ParserMatchClass = MemNMU12Parser; } -def mem_nm_sp5s2 : mem_generic { - let EncoderMethod = "getMemEncodingNMSP"; - let ParserMatchClass = NMMemSPAsmOperand<7,4>; - let OperandNamespace = "NanoMips"; - let OperandType = "OPERAND_NM_SPREL7"; +def MemNMS9Parser : NMMemSimmAsmOperand<9,0, + "Mips::GPRNM32RegClassID",[MemNMGP19S2Parser]>; + +def mem_nms9 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm9"; + let DecoderMethod = "DecodeMemNM<9,true,Mips::GPRNM32RegClassID>"; + let ParserMatchClass = MemNMS9Parser; +} + +def mem_nmpcrel : mem_generic { + let EncoderMethod = "getMemEncodingNMImm9"; + let ParserMatchClass = MipsMemSimmAsmOperand<9>; +} + +def mem_nmrx : mem_generic { + let EncoderMethod = "getMemEncodingNMRX"; + let ParserMatchClass = MipsMemRxAsmOperand; } foreach I = {4, 7, 10, 11, 14, 25} in @@ -572,11 +609,13 @@ class Arith4x4_Desc { Format Form = FrmR; + let Constraints = "$rt = $dst"; } class Arith4x4_Enc isel>: _Pool_P16_4X4 { bits<5> dst; bits<5> rs; + bits<5> rt; let Inst{9} = dst{4}; let Inst{7...5} = dst{2...0}; @@ -917,7 +956,6 @@ class LoadMemoryNM { - let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; let mayLoad = 1; string BaseOpcode = opstr; @@ -950,14 +988,13 @@ class StoreMemoryX : - InstNM<(outs GPRNM3Opnd:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set GPRNM3Opnd:$rt, (OpNode Addr:$addr))], + InstNM<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, (OpNode Addr:$addr))], itin> { - let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; let mayLoad = 1; string BaseOpcode = opstr; @@ -970,19 +1007,17 @@ class StoreMemoryNM { - let DecoderMethod = "DecodeMem"; let mayStore = 1; string BaseOpcode = opstr; } -class StoreMemoryNM16 : - InstNM<(outs), (ins GPRNM3ZOpnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode GPRNM3ZOpnd:$rt, Addr:$addr)], + InstNM<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RO:$rt, Addr:$addr)], itin> { - let DecoderMethod = "DecodeMem"; let mayStore = 1; string BaseOpcode = opstr; } @@ -1625,31 +1660,31 @@ def : NMPat<(brcond (i32 (seteq (and GPRNM32:$rt, simm32power2:$imm), 0)), bb:$o // Load / store instructions // //===----------------------------------------------------------------------===// -def LWSP16_NM : LoadMemoryNM16<"lw", mem_nm_sp5s2, load, addrsp5s2, II_LW>, +def LWSP16_NM : LoadMemoryNM16<"lw", GPRNM32Opnd, mem_nm_sp5s2, load, addrsp5s2, II_LW>, LSSPRegMem16_Enc<0b00101>; // Broken -def SWSP16_NM : StoreMemoryNM16<"sw", mem_nm_sp5s2, store, addrsp5s2, II_SW>, +def SWSP16_NM : StoreMemoryNM16<"sw", GPRNM32Opnd, mem_nm_sp5s2, store, addrsp5s2, II_SW>, LSSPRegMem16_Enc<0b10101>; // Broken -def LWGP16_NM : LoadMemoryNM16<"lw", mem_nm_gp7s2, load, addrgp7s2, II_LW>, +def LWGP16_NM : LoadMemoryNM16<"lw", GPRNM3Opnd, mem_nm_gp7s2, load, addrgp7s2, II_LW>, LSGPRegMem16_Enc<0b01001>; -def SWGP16_NM : StoreMemoryNM16<"sw", mem_nm_gp7s2, store, addrgp7s2, II_SW>, +def SWGP16_NM : StoreMemoryNM16<"sw", GPRNM3ZOpnd, mem_nm_gp7s2, store, addrgp7s2, II_SW>, LSGPRegMem16_Enc<0b11001>; -def LW16_NM : LoadMemoryNM16<"lw", mem_nm6s2, load, addruimm6s2, II_LW>, +def LW16_NM : LoadMemoryNM16<"lw", GPRNM3Opnd, mem_nm6s2, load, addruimm6s2, II_LW>, LSMem16_Enc<0b00001>; -def SW16_NM : StoreMemoryNM16<"sw", mem_nm6s2, store, addruimm6s2, II_SW>, +def SW16_NM : StoreMemoryNM16<"sw", GPRNM3ZOpnd, mem_nm6s2, store, addruimm6s2, II_SW>, LSMem16_Enc<0b10001>; -def LH16_NM : LoadMemoryNM16<"lh", mem_nm3s1, sextloadi16, addruimm3s1, II_LH>, +def LH16_NM : LoadMemoryNM16<"lh", GPRNM3Opnd, mem_nm3s1, sextloadi16, addruimm3s1, II_LH>, LHMem16_Enc<0b00>; -def LHU16_NM : LoadMemoryNM16<"lhu", mem_nm3s1, zextloadi16, addruimm3s1, II_LH>, +def LHU16_NM : LoadMemoryNM16<"lhu", GPRNM3Opnd, mem_nm3s1, zextloadi16, addruimm3s1, II_LH>, LHMem16_Enc<0b10>; -def SH16_NM : StoreMemoryNM16<"sh", mem_nm3s1, truncstorei16, addruimm3s1, II_SH>, +def SH16_NM : StoreMemoryNM16<"sh", GPRNM3ZOpnd, mem_nm3s1, truncstorei16, addruimm3s1, II_SH>, LHMem16_Enc<0b01>; -def LB16_NM : LoadMemoryNM16<"lb", mem_nm2, sextloadi8, addruimm2, II_LB>, +def LB16_NM : LoadMemoryNM16<"lb", GPRNM3Opnd, mem_nm2, sextloadi8, addruimm2, II_LB>, LBMem16_Enc<0b00>; -def LBU16_NM : LoadMemoryNM16<"lbu", mem_nm2, zextloadi8, addruimm2, II_LB>, +def LBU16_NM : LoadMemoryNM16<"lbu", GPRNM3Opnd, mem_nm2, zextloadi8, addruimm2, II_LB>, LBMem16_Enc<0b10>; -def SB16_NM : StoreMemoryNM16<"sb", mem_nm2, truncstorei8, addruimm2, II_SB>, +def SB16_NM : StoreMemoryNM16<"sb", GPRNM3ZOpnd, mem_nm2, truncstorei8, addruimm2, II_SB>, LBMem16_Enc<0b01>; def LWGP_NM : LoadMemoryNM<"lw", mem_nm_gp19s2, load, addrgp19s2, II_LW>, From 19915a6dfecd9e749adbed152b013133c824cb5d Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 30 Dec 2022 15:43:46 +0530 Subject: [PATCH 047/123] Add encoding for MOVE_NM and refactor to MOVE16_NM --- .../Target/Mips/Disassembler/MipsDisassembler.cpp | 2 +- llvm/lib/Target/Mips/MipsInstrInfo.cpp | 4 ++-- llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 4 ++-- llvm/lib/Target/Mips/MipsSERegisterInfo.cpp | 2 +- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 3 ++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 15 +++++++++++++-- llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp | 4 ++-- 7 files changed, 23 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 73e92b7abd56f..a65a72292a489 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1643,7 +1643,7 @@ static DecodeStatus DecodeGPRNM32NZRegisterClass(MCInst &Inst, const void *Decoder) { if (RegNo == 0) return MCDisassembler::Fail; - unsigned Reg = getReg(Decoder, Mips::GPRNM32NZRegClassID, RegNo); + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index d38ee8956cc3e..8b2a44ee6e522 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -1293,11 +1293,11 @@ MachineBasicBlock::iterator MipsInstrInfo::insertOutlinedCall( assert(Reg != 0 && "No callee-saved register available?"); // save RA + restore RA from Reg (available register) - SaveRA = BuildMI(MF, DebugLoc(), get(Mips::MOVE_NM)) + SaveRA = BuildMI(MF, DebugLoc(), get(Mips::MOVE16_NM)) .addReg(Reg, RegState::Define) .addReg(Mips::RA_NM); - RestoreRA = BuildMI(MF, DebugLoc(), get(Mips::MOVE_NM)) + RestoreRA = BuildMI(MF, DebugLoc(), get(Mips::MOVE16_NM)) .addReg(Mips::RA_NM, RegState::Define) .addReg(Reg); diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index 2fe74e3e1d0e8..75ac31e31c883 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -171,8 +171,8 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, Opc = Mips::MOVE_V; } else if (Mips::GPRNM32RegClass.contains(SrcReg)) { - if (Mips::GPRNM32RegClass.contains(DestReg)) - Opc = Mips::MOVE_NM; + if (Mips::GPRNM32NZRegClass.contains(DestReg)) + Opc = Mips::MOVE16_NM; } assert(Opc && "Cannot copy registers"); diff --git a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp index 71ddbec8fa8ca..222315753f03f 100644 --- a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -231,7 +231,7 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, const MipsSEInstrInfo &TII = *static_cast( MBB.getParent()->getSubtarget().getInstrInfo()); DebugLoc DL = MI.getDebugLoc(); - BuildMI(MBB, II, DL, TII.get(Mips::MOVE_NM), MI.getOperand(0).getReg()) + BuildMI(MBB, II, DL, TII.get(Mips::MOVE16_NM), MI.getOperand(0).getReg()) .addReg(FrameReg); MI.eraseFromParent(); return; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 7302abe6cefd3..cd34204da4935 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -123,7 +123,8 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, LAGPB_NM, LUI_NM, - LSA_NM, MOVEP_NM, MOVE_NM, MOD_NM, MODU_NM, + LSA_NM, MOVEP_NM, MOVE16_NM, MOD_NM, MODU_NM, + MOVE16_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, NOT_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, ROTR_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index af12b17a9b12e..1fb39d41b1bdb 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1544,6 +1544,14 @@ class BBit_Enc isel> : _Pool_P_BRI let Inst{0} = offset{11}; } +class MOVE_Enc isel> : _Pool_P16<0b00000> +{ + bits<5> rt; + bits<5> rs; + let Inst{9...5} = rt; + let Inst{4...0} = rs; +} + def BC_NM : BCBase, BC32_Enc<0b0>; def BALC_NM : CallNM<"balc", MipsJmpLink, calltarget25_nm>, BC32_Enc<0b1>; def BC16_NM : BCBase, BC16_Enc<0b00010>; @@ -1787,12 +1795,15 @@ def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000> def SWPC_NM : StorePCBase, Op48_Enc<0b01011>; def LWPC_NM : LoadPCBase, Op48_Enc<0b01111>; +def MOVE16_NM : InstNM<(outs GPRNM32NZOpnd:$rt), (ins GPRNM32Opnd:$rs), + "move\t$rt, $rs", []>, MOVE_Enc<0b00100> { + let isMoveReg = 1; +} + let isCodeGenOnly = 1 in { // TODO: Halfword load/store is never selected, this needs to be looked into. -def MOVE_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), - "move\t$rt, $rs", []>, InstSize16; def MOVEP_NM : InstNM<(outs GPRNM32Opnd:$dst1, GPRNM32Opnd:$dst2), (ins GPRNM32Opnd:$src1, GPRNM32Opnd:$src2), "movep\t$dst1, $dst2, $src1, $src2", []>, InstSize16; diff --git a/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp index 49fcad87a2ae0..82305a3fccefe 100644 --- a/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp @@ -202,7 +202,7 @@ bool NMMoveOpt::generateMoveP(MachineBasicBlock &MBB) { }; for (auto &MI : MBB) { - if (MI.getOpcode() == Mips::MOVE_NM) { + if (MI.getOpcode() == Mips::MOVE16_NM) { if (PrevMove) { bool Swap; if (areMovePRevCompatibleMoves(PrevMove, &MI, Swap) || @@ -303,7 +303,7 @@ bool NMMoveOpt::generateMoveBalc(MachineBasicBlock &MBB) { if (MI2.isCFIInstruction() || MI2.isDebugInstr()) continue; - if (MI2.getOpcode() == Mips::MOVE_NM && + if (MI2.getOpcode() == Mips::MOVE16_NM && // Make sure $rt is used only by BALC. CandidateDstRegs.contains(MI2.getOperand(0).getReg()) && // Make sure $rs is not redefined between MOVE and BALC. From ed2143fd62a551f8504c45301ff0f2fa913fb89c Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 30 Dec 2022 15:47:50 +0530 Subject: [PATCH 048/123] Clean-up redundant TODO comments --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 31 ++--------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 1fb39d41b1bdb..f2b7e07bca7b9 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -481,10 +481,6 @@ class _Pool_P16_MV psel> : _Pool_P16<0b00000> { let Inst{9...5} = psel; } -// TODO LW16 psel> : _Pool_P16<0b00001> - -// TODO BC16 : _Pool_P16<0b00010> - class _Pool_P16_SR psel> : _Pool_P16<0b00011> { let Inst{8} = psel; } @@ -493,10 +489,6 @@ class _Pool_P16_SHIFT psel> : _Pool_P16<0b00100> { let Inst{3} = psel; } -// TODO LW_SP : _Pool_P16<0b00101> - -// TODO BALC16 : _Pool_P16<0b00110> - class _Pool_P16_4X4 psel> : _Pool_P16<0b00111> { let Inst{8} = psel{1}; let Inst{3} = psel{0}; @@ -511,8 +503,6 @@ class _Pool_POOL16C_00 psel> : _Pool_P16<0b01000> { let Inst{1...0} = 0b00; } -// TODO LW_GP16 : _Pool_P16<0b01001> - class _Pool_P16_LB psel> : _Pool_P16<0b01011> { let Inst{3...2} = psel; } @@ -532,25 +522,18 @@ class _Pool_P16_A2 psel> : _Pool_P16<0b10000> { let Inst{3} = psel; } -//TODO SW_16 : _Pool_P16<0b10001> - //TODO BEQZC_16 : _Pool_P16<0b10010> - class _Pool_P16_ADDU psel> : _Pool_P16<0b10100> { let Inst{0} = psel; } -//TODO SW_SP : _Pool_P16<0b10101> - // TODO BNEZC_16 : _Pool_P16<0b10110> // TODO MOVEP : _Pool_P16<0b10111> // TODO LI16 : _Pool_P16<0b11000> -// TODO SW_GP16 : _Pool_P16<0b10001> - class _Pool_P16_BR psel> : _Pool_P16<0b11010> { let Inst{3...0} = psel; } @@ -563,8 +546,6 @@ class _Pool_P16_SYSCALL psel> : _Pool_P16_RI<0b01> { let Inst{2} = psel; } -// TODO MOVE_16 : _Pool_P16_RI - // TODO ANDI_16 : _Pool_P16<0b11100> // TODO SW_4X4 : _Pool_P16<0b11101> @@ -600,8 +581,6 @@ class _Pool_PP_LSX isel> : _Pool_POOL32A7<0b000> { let Inst{10...7} = isel; } -// TODO BC_32 : _Pool_P_BAL<0b0> - // 16-bit arithmetic and logical instructions with 4x4 register operands, P16_4X4 class Arith4x4_Desc: @@ -1593,16 +1572,12 @@ def BLTIUC_NM : CBranchImmNM<"bltiuc", brtarget11_nm, setult, GPRNM32Opnd, uimm7 BRI_Enc<0b111>; // Bit-test branches +let hasNoSchedulingInfo = 1, + hasDelaySlot = 0 in { def BBNEZC_NM : CBranchBitNM<"bbnezc", brtarget11_nm, setne, GPRNM32Opnd, simm32, simm32power2>, BBit_Enc<0b001>; def BBEQZC_NM : CBranchBitNM<"bbeqzc", brtarget11_nm, seteq, GPRNM32Opnd, simm32, simm32power2>, BBit_Enc<0b101>; - -let isCodeGenOnly = 1, hasNoSchedulingInfo = 1, - hasDelaySlot = 0 in { - -// TODO: BBEQZ/BBNEZ bit-test conditional branch instructions - } class TailCallBase : PseudoInstNM<(outs), (ins calltarget25_nm:$target), []>, @@ -1802,8 +1777,6 @@ def MOVE16_NM : InstNM<(outs GPRNM32NZOpnd:$rt), (ins GPRNM32Opnd:$rs), let isCodeGenOnly = 1 in { -// TODO: Halfword load/store is never selected, this needs to be looked into. - def MOVEP_NM : InstNM<(outs GPRNM32Opnd:$dst1, GPRNM32Opnd:$dst2), (ins GPRNM32Opnd:$src1, GPRNM32Opnd:$src2), "movep\t$dst1, $dst2, $src1, $src2", []>, InstSize16; From 8faff245e831673ec0d9665d278c0c2c23d34284 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 1 Jan 2023 07:18:12 +0530 Subject: [PATCH 049/123] Add MOVEP[/REV] and 2R register encodings, fix 4x4Z encoding --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 63 ++++++++++++++++--- .../Mips/Disassembler/MipsDisassembler.cpp | 37 +++++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 20 ++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 4 ++ llvm/lib/Target/Mips/MipsRegisterInfo.td | 41 +++++++++++- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 53 +++++++++++----- 7 files changed, 196 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 7e2f01745312a..5bd84a9c845ca 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -520,6 +520,8 @@ class MipsAsmParser : public MCTargetAsmParser { Match_RequiresPosSizeRange0_32, Match_RequiresPosSizeRange33_64, Match_RequiresPosSizeUImm6, + Match_RequiresDstRegPair, + Match_RequiresSrcRegPair, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "MipsGenAsmMatcher.inc" #undef GET_OPERAND_DIAGNOSTIC_TYPES @@ -942,6 +944,15 @@ class MipsOperand : public MCParsedAsmOperand { return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); } + unsigned getGPRNM4ZeroReg() const { + assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); + unsigned ClassID = Mips::GPRNM32RegClassID; + unsigned RegNo = RegIdx.Index; + if (RegNo == 0) + RegNo = 11; + return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + /// Coerce the register to GPR64 and return the real register for the current /// target. unsigned getGPR64Reg() const { @@ -1131,6 +1142,11 @@ class MipsOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(getGPRNM32Reg())); } + void addGPRNM4ZAsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createReg(getGPRNM4ZeroReg())); + } + /// Render the operand to an MCInst as a GPR64 /// Asserts if the wrong number of operands are requested, or the operand /// is not a k_RegisterIndex compatible with RegKind_GPR @@ -1879,7 +1895,7 @@ class MipsOperand : public MCParsedAsmOperand { (RegNo >= 17 && RegNo <= 19)); } - bool isNM4x4AsmReg() const { + bool isNM4AsmReg() const { if (!(isRegIdx() && RegIdx.Kind)) return false; return ((RegIdx.Index >= 4 && RegIdx.Index <= 11) @@ -1887,7 +1903,7 @@ class MipsOperand : public MCParsedAsmOperand { } - bool isNM4x4ZeroAsmReg() const { + bool isNM4ZeroAsmReg() const { if (!(isRegIdx() && RegIdx.Kind)) return false; return ((RegIdx.Index == 0) || @@ -1895,13 +1911,28 @@ class MipsOperand : public MCParsedAsmOperand { (RegIdx.Index >= 16 && RegIdx.Index <= 23)); } + bool isNM2R1AsmReg() const { + volatile unsigned RegNo = RegIdx.Index; + if (!(isRegIdx() && RegIdx.Kind)) + return false; + return (RegNo >= 4 && RegNo <= 7); + } + + bool isNM2R2AsmReg() const { + if (!(isRegIdx() && RegIdx.Kind)) + return false; + return (RegIdx.Index >= 5 && RegIdx.Index <= 8); + } + enum NM_REG_TYPE { NMR, NMR_NZ, NMR_3, NMR_3Z, NMR_4, - NMR_4Z + NMR_4Z, + NMR_2R1, + NMR_2R2 }; template @@ -1920,9 +1951,13 @@ class MipsOperand : public MCParsedAsmOperand { case Mips::GPRNM3ZRegClassID: return isNM16ZeroAsmReg(); case Mips::GPRNM4RegClassID: - return isNM4x4AsmReg(); - case Mips::GPRNM4ZeroRegClassID: - return isNM4x4ZeroAsmReg(); + return isNM4AsmReg(); + case Mips::GPRNM4ZRegClassID: + return isNM4ZeroAsmReg(); + case Mips::GPRNM2R1RegClassID: + return isNM2R1AsmReg(); + case Mips::GPRNM2R2RegClassID: + return isNM2R2AsmReg(); default: return (RegIdx.Index < 32); } @@ -6160,7 +6195,15 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { case Mips::MUL4x4_NM: if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg()) return Match_RequiresSameSrcAndDst; - return Match_Success; + return Match_Success; + case Mips::MOVEP_NM: + if (Inst.getOperand(1).getReg() != Inst.getOperand(0).getReg() + 1) + return Match_RequiresDstRegPair; + return Match_Success; + case Mips::MOVEPREV_NM: + if (Inst.getOperand(3).getReg() != Inst.getOperand(2).getReg() + 1) + return Match_RequiresSrcRegPair; + return Match_Success; } uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags; @@ -6230,6 +6273,10 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(IDLoc, "invalid operand ($zero) for instruction"); case Match_RequiresSameSrcAndDst: return Error(IDLoc, "source and destination must match"); + case Match_RequiresDstRegPair: + return Error(IDLoc, "destination registers must be in sequence"); + case Match_RequiresSrcRegPair: + return Error(IDLoc, "source registers must be in sequence"); case Match_NoFCCRegisterForCurrentISA: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "non-zero fcc register doesn't exist in current ISA level"); @@ -7245,7 +7292,7 @@ bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, getTargetStreamer().forbidModuleDirective(); // Check if we have valid mnemonic - if (!mnemonicIsValid(Name, 0)) { + if (!mnemonicIsValid(Name, 0) && !mnemonicIsValid(Name, 1)) { FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS); return Error(NameLoc, "unknown instruction" + Suggestion); diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index a65a72292a489..52060170d3ef4 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -141,6 +141,16 @@ static DecodeStatus DecodeGPRNM32RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRNM2R1RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeGPRNM2R2RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1616,6 +1626,7 @@ static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, const void *Decoder) { if (RegNo > 31) return MCDisassembler::Fail; + RegNo &= ~0x8; RegNo += (RegNo < 4 ? 8 : 0); unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); Inst.addOperand(MCOperand::createReg(Reg)); @@ -1628,6 +1639,7 @@ static DecodeStatus DecodeGPRNM4ZRegisterClass(MCInst &Inst, const void *Decoder) { if (RegNo > 31) return MCDisassembler::Fail; + RegNo &= ~0x8; if (RegNo == 3) RegNo = 0; else @@ -1659,6 +1671,31 @@ static DecodeStatus DecodeGPRNM32RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPRNM2R1RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + RegNo += 4; + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + Inst.addOperand(MCOperand::createReg(Reg+1)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeGPRNM2R2RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + RegNo += 5; + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 1c5eb692289e8..b6af8a7bcfed5 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -237,6 +237,8 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, emitInstruction(Binary, Size, STI, OS); } + + /// getBranchTargetOpValue - Return binary encoding of the branch /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. @@ -1479,4 +1481,22 @@ MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, return Res >> 2; } +unsigned +MipsMCCodeEmitter::getGPRNM4x4ZeroReg(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + MCOperand Op = MI.getOperand(OpNo); + assert(Op.isReg() && "Operand of movep is not a register!"); + unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Op.getReg()); + switch (Op.getReg()) { + default: + return RegNo; + case Mips::ZERO_NM: return 11; + case Mips::A4_NM: + case Mips::A5_NM: + case Mips::A6_NM: + return RegNo - 8; + } +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 01a9577ab7174..4bab3825c6f36 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -332,6 +332,10 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getGPRNM4x4ZeroReg(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + private: void LowerCompactBranch(MCInst& Inst) const; }; diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index de526d5991c95..2f99941459842 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -359,7 +359,7 @@ def GPRNM4 : S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM)>; // nanoMIPS "gpr4x4.zero" register encoding type. -def GPRNM4Zero : +def GPRNM4Z : RegisterClass<"Mips", [i32], 32, (add A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM, S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM)>; @@ -376,6 +376,14 @@ def GPRNMSP : RegisterClass<"Mips", [i32], 32, (add SP_NM)>; def GPRNMGP : RegisterClass<"Mips", [i32], 32, (add GP_NM)>; +// nanoMIPS "gpr2.reg1" & "gpr2.reg2" register encoding types. +def GPRNM2R1 : + RegisterClass<"Mips", [i32], 32, + (add A0_NM, A1_NM, A2_NM, A3_NM)>; +def GPRNM2R2 : + RegisterClass<"Mips", [i32], 32, + (add A1_NM, A2_NM, A3_NM, A4_NM)>; + class GPR32Class regTypes> : RegisterClass<"Mips", regTypes, 32, (add // Reserved @@ -671,12 +679,30 @@ class GPRNM4x4AsmOperandClass Supers = []> : MipsAsmRegOpe let PredicateMethod = "isGPRNMAsmReg"; } +class GPRNM4x4ZeroAsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNM4x4ZeroAsmReg"; + let PredicateMethod = "isGPRNMAsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; +} + class GPRNM32NZAsmOperandClass Supers = []> : MipsAsmRegOperand { let Name = "GPRNMNonZeroAsmReg"; let RenderMethod = "addGPRNM32AsmRegOperands"; let PredicateMethod = "isGPRNMAsmReg"; } +class GPRNM2R1AsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNM2R1AsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; + let PredicateMethod = "isGPRNMAsmReg"; +} + +class GPRNM2R2AsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNM2R2AsmReg"; + let RenderMethod = "addGPRNM32AsmRegOperands"; + let PredicateMethod = "isGPRNMAsmReg"; +} + def GPRMM16AsmOperandZero : MipsAsmRegOperand { let Name = "GPRMM16AsmRegZero"; let PredicateMethod = "isMM16AsmRegZero"; @@ -786,10 +812,23 @@ def GPRNM3ZOpnd : RegisterOperand { let ParserMatchClass = GPRNM16ZeroAsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; } +def GPRNM2R1Opnd : RegisterOperand { + let ParserMatchClass = GPRNM2R1AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; +} + +def GPRNM2R2Opnd : RegisterOperand { + let ParserMatchClass = GPRNM2R2AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; +} + def GPRNM4Opnd : RegisterOperand { let ParserMatchClass = GPRNM4x4AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; } +def GPRNM4ZOpnd : RegisterOperand { + let ParserMatchClass = GPRNM4x4ZeroAsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; + let EncoderMethod = "getGPRNM4x4ZeroReg"; +} + def GPRNM32NZOpnd : RegisterOperand { let ParserMatchClass = GPRNM32NZAsmOperandClass<[GPRNM4Opnd.ParserMatchClass]>; } diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index cd34204da4935..74398db10b501 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -124,7 +124,7 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, LAGPB_NM, LUI_NM, LSA_NM, MOVEP_NM, MOVE16_NM, MOD_NM, MODU_NM, - MOVE16_NM, + MOVEPREV_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, NOT_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, ROTR_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index f2b7e07bca7b9..f9ebae838047b 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -530,8 +530,6 @@ class _Pool_P16_ADDU psel> : _Pool_P16<0b10100> { // TODO BNEZC_16 : _Pool_P16<0b10110> -// TODO MOVEP : _Pool_P16<0b10111> - // TODO LI16 : _Pool_P16<0b11000> class _Pool_P16_BR psel> : _Pool_P16<0b11010> { @@ -550,9 +548,6 @@ class _Pool_P16_SYSCALL psel> : _Pool_P16_RI<0b01> { // TODO SW_4X4 : _Pool_P16<0b11101> -// TODO MOVEP_REV : _Pool_P16<0b11111> - - class _Pool_P_RI psel> : _Pool_P_ADDIU<0b00000> { let Inst{20...19} = psel; @@ -1523,7 +1518,7 @@ class BBit_Enc isel> : _Pool_P_BRI let Inst{0} = offset{11}; } -class MOVE_Enc isel> : _Pool_P16<0b00000> +class MOVE_Enc isel> : _Pool_P16 { bits<5> rt; bits<5> rs; @@ -1531,6 +1526,34 @@ class MOVE_Enc isel> : _Pool_P16<0b00000> let Inst{4...0} = rs; } +class MOVEP_Enc isel> : _Pool_P16 +{ + bits<2> dst1; + bits<5> src1; + bits<5> src2; + + let Inst{9} = src2{4}; + let Inst{7...5} = src2{2...0}; + let Inst{4} = src1{4}; + let Inst{2...0} = src1{2...0}; + let Inst{8} = dst1{0}; + let Inst{3} = dst1{1}; +} + +class MOVEPREV_Enc isel> : _Pool_P16 +{ + bits<2> src1; + bits<5> dst1; + bits<5> dst2; + + let Inst{9} = dst2{4}; + let Inst{7...5} = dst2{2...0}; + let Inst{4} = dst1{4}; + let Inst{2...0} = dst1{2...0}; + let Inst{8} = src1{0}; + let Inst{3} = src1{1}; +} + def BC_NM : BCBase, BC32_Enc<0b0>; def BALC_NM : CallNM<"balc", MipsJmpLink, calltarget25_nm>, BC32_Enc<0b1>; def BC16_NM : BCBase, BC16_Enc<0b00010>; @@ -1770,17 +1793,19 @@ def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000> def SWPC_NM : StorePCBase, Op48_Enc<0b01011>; def LWPC_NM : LoadPCBase, Op48_Enc<0b01111>; +let isMoveReg = 1 in { def MOVE16_NM : InstNM<(outs GPRNM32NZOpnd:$rt), (ins GPRNM32Opnd:$rs), - "move\t$rt, $rs", []>, MOVE_Enc<0b00100> { - let isMoveReg = 1; -} - -let isCodeGenOnly = 1 in { + "move\t$rt, $rs", []>, MOVE_Enc<0b00100>; -def MOVEP_NM : InstNM<(outs GPRNM32Opnd:$dst1, GPRNM32Opnd:$dst2), - (ins GPRNM32Opnd:$src1, GPRNM32Opnd:$src2), - "movep\t$dst1, $dst2, $src1, $src2", []>, InstSize16; +def MOVEP_NM : InstNM<(outs GPRNM2R1Opnd:$dst1, GPRNM2R2Opnd:$dst2), + (ins GPRNM4ZOpnd:$src1, GPRNM4ZOpnd:$src2), + "movep\t$dst1, $dst2, $src1, $src2", []>, + MOVEP_Enc<0b10111>; +def MOVEPREV_NM : InstNM<(outs GPRNM4Opnd:$dst1, GPRNM4Opnd:$dst2), + (ins GPRNM2R1Opnd:$src1, GPRNM2R2Opnd:$src2), + "movep\t$dst1, $dst2, $src1, $src2", []>, + MOVEPREV_Enc<0b11111>; } // These patterns help generate better loads/stores when the immediate doesn't From f962dab91ed07c0b5502c7d376619578c22b2aa4 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 1 Jan 2023 16:23:44 +0530 Subject: [PATCH 050/123] Add LW/SW[4x4] and 4x4 base register encoding/decoding logic --- .../Mips/Disassembler/MipsDisassembler.cpp | 24 ++++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 31 +++++++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 7 +++ llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 6 +++ llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 3 ++ llvm/lib/Target/Mips/MipsRegisterInfo.td | 1 + llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 5 +++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 2 + llvm/lib/Target/Mips/MipsScheduleGeneric.td | 4 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 44 ++++++++++++++++--- 10 files changed, 120 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 52060170d3ef4..35833642ced47 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -340,6 +340,11 @@ static DecodeStatus DecodeMemNM(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemNM4x4(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1811,6 +1816,10 @@ static DecodeStatus DecodeMemNM(MCInst &Inst, case Mips::GPRNM3RegClassID: Base = fieldFromInstruction(Insn, Offbits, 3); break; + case Mips::GPRNM4RegClassID: + case Mips::GPRNM4ZRegClassID: + assert(false && "Unexpected register class."); + break; default: Base = fieldFromInstruction(Insn, Offbits, 5); } @@ -1826,6 +1835,21 @@ static DecodeStatus DecodeMemNM(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeMemNM4x4(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + int Offset = (Insn & 0x8) | (Insn & 0x100) >> 6; + unsigned Base; + + Base = getReg(Decoder, Mips::GPRNM4RegClassID, + fieldFromInstruction(Insn, 0, 5) & ~0x8); + + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + + return MCDisassembler::Success; +} static DecodeStatus DecodeMemEVA(MCInst &Inst, unsigned Insn, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index b6af8a7bcfed5..2d96b86d1efa8 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1255,6 +1255,19 @@ getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, return (OffBits & 0x3) | RegBits; } +unsigned MipsMCCodeEmitter:: +getMemEncodingNMImm2S2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Base register is encoded in bits 7-4, offset is encoded in bits 3-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, + STI) << 4; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + + return (OffBits & 0xc) | RegBits; +} + unsigned MipsMCCodeEmitter:: getMemEncodingNMGP(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, @@ -1499,4 +1512,22 @@ MipsMCCodeEmitter::getGPRNM4x4ZeroReg(const MCInst &MI, unsigned OpNo, } } +unsigned +MipsMCCodeEmitter::getGPRNM4x4Reg(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + MCOperand Op = MI.getOperand(OpNo); + assert(Op.isReg() && "Operand of movep is not a register!"); + unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Op.getReg()); + switch (Op.getReg()) { + default: + return RegNo; + case Mips::A4_NM: + case Mips::A5_NM: + case Mips::A6_NM: + case Mips::A7_NM: + return RegNo - 8; + } +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 4bab3825c6f36..f5b1dfe974b6b 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -267,6 +267,9 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMImm2S2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMemEncodingNMGP(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; @@ -336,6 +339,10 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getGPRNM4x4Reg(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + private: void LowerCompactBranch(MCInst& Inst) const; }; diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 9146beab2ea4d..afc3a0f793e85 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -195,6 +195,12 @@ bool MipsDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, return false; } +bool MipsDAGToDAGISel::selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + bool MipsDAGToDAGISel::selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, SDValue &Offset) const { llvm_unreachable("Unimplemented function."); diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 62ef8fdab4e14..e20fe00b40f38 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -116,6 +116,9 @@ class MipsDAGToDAGISel : public SelectionDAGISel { virtual bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, SDValue &Offset) const; + virtual bool selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + virtual bool selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, SDValue &Offset) const; diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index 2f99941459842..d59114df69917 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -822,6 +822,7 @@ def GPRNM2R2Opnd : RegisterOperand { def GPRNM4Opnd : RegisterOperand { let ParserMatchClass = GPRNM4x4AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; + let EncoderMethod = "getGPRNM4x4Reg"; } def GPRNM4ZOpnd : RegisterOperand { diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index f0befed36c28f..a00e4f39660c9 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -571,6 +571,11 @@ bool MipsSEDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, return selectAddrFrameIndexUOffset(Addr, Base, Offset, 2); } +bool MipsSEDAGToDAGISel::selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrFrameIndexUOffset(Addr, Base, Offset, 2, 2); +} + bool MipsSEDAGToDAGISel::selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, SDValue &Offset) const { return selectAddrFrameIndexUOffset(Addr, Base, Offset, 19, 2); diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index b43e1d154ae79..7a45a29257dad 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -117,6 +117,8 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel { bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + bool selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + bool selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; bool selectIntAddrUImm18(SDValue Addr, SDValue &Base, SDValue &Offset) const override; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 74398db10b501..ae9dc900bdb30 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -720,12 +720,12 @@ def : InstRW<[GenericWriteLoad], (instrs LW_NM, LWGP_NM, LWs9_NM, UALH_NM, UALW_NM, LWM_NM, UALWM_NM, LWPC_NM, LW16_NM, LH16_NM, LHU16_NM, LB16_NM, LBU16_NM, LBGP_NM, LBUGP_NM, - LHGP_NM, LHUGP_NM)>; + LHGP_NM, LHUGP_NM, LW4x4_NM)>; def: InstRW<[GenericWriteStore], (instrs SW_NM, SWs9_NM, SW16_NM, SH16_NM, SH_NM, SHs9_NM, SWGP_NM, SBGP_NM, SHGP_NM, SB_NM, SBs9_NM, SB16_NM, LWGP16_NM, SWGP16_NM, - LWSP16_NM, SWSP16_NM, + LWSP16_NM, SWSP16_NM, SW4x4_NM, SWX_NM, SWXS_NM, SHX_NM, SHXS_NM, SBX_NM, UASH_NM, UASW_NM, SWM_NM, UASWM_NM, SWPC_NM)>; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index f9ebae838047b..a5c532fccf316 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -182,6 +182,8 @@ def MemNM3S1Parser : NMMemUimmAsmOperand<3,1,"Mips::GPRNM3RegClassID",[MemNMSP5S2Parser]>; def MemNM2Parser : NMMemUimmAsmOperand<2,0,"Mips::GPRNM3RegClassID",[MemNMSP5S2Parser]>; +def MemNM2S2Parser : + NMMemUimmAsmOperand<2,2,"Mips::GPRNM4RegClassID",[MemNMSP5S2Parser]>; def mem_nm6s2 : mem_generic { let EncoderMethod = "getMemEncodingNMImm6S2"; @@ -199,6 +201,12 @@ def mem_nm2 : mem_generic { let ParserMatchClass = MemNM2Parser; } +def mem_nm2s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm2S2"; + let ParserMatchClass = MemNM2S2Parser; + let DecoderMethod = "DecodeMemNM4x4"; +} + def MemNMGP19S2Parser : NMMemUimmAsmOperand<19,2, "Mips::GPRNMGPRegClassID",[MemNMGP7S2Parser]>; @@ -306,6 +314,7 @@ def addrindexedlsl2 : ComplexPattern; def addruimm6s2 : ComplexPattern; def addruimm3s1 : ComplexPattern; def addruimm2 : ComplexPattern; +def addruimm2s2 : ComplexPattern; def addrgp19s2 : ComplexPattern; def addrgp18 : ComplexPattern; def addrgp17s1 : ComplexPattern; @@ -511,8 +520,6 @@ class _Pool_P16_A1 psel> : _Pool_P16<0b01100> { let Inst{6} = psel; } -// TODO LW_4X4 : _Pool_P16<0b01101> { - class _Pool_P16_LH psel> : _Pool_P16<0b01111> { let Inst{3} = psel{1}; let Inst{0} = psel{0}; @@ -546,9 +553,6 @@ class _Pool_P16_SYSCALL psel> : _Pool_P16_RI<0b01> { // TODO ANDI_16 : _Pool_P16<0b11100> -// TODO SW_4X4 : _Pool_P16<0b11101> - - class _Pool_P_RI psel> : _Pool_P_ADDIU<0b00000> { let Inst{20...19} = psel; } @@ -923,6 +927,20 @@ class LSMemGP17S1_Enc isel> : _Pool_P_GP_BH let Inst{0} = isel{0}; } +class LSMem4x4_Enc isel> : _Pool_P16 +{ + bits<5> rt; + bits<9> addr; + bits<5> rs = addr{8...4}; + bits<4> offset = addr{3...0}; + let Inst{9} = rt{4}; + let Inst{7...5} = rt{2...0}; + let Inst{4} = rs{4}; + let Inst{2...0} = rs{2...0}; + let Inst{3} = offset{3}; + let Inst{8} = offset{2}; +} + class LoadMemoryNM : + InstNM<(outs), (ins GPRNM4ZOpnd:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode GPRNM4ZOpnd:$rt, Addr:$addr)], + itin> { + let mayStore = 1; + string BaseOpcode = opstr; +} + class Op48_Enc isel> : _Pool_P48I { bits<5> rt; bits<32> addr; @@ -1790,6 +1819,11 @@ def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000> //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; +def LW4x4_NM : LoadMemoryNM16<"lw", GPRNM4Opnd, mem_nm2s2, load, addruimm2s2, II_LW>, + LSMem4x4_Enc<0b01101>; +def SW4x4_NM : StoreMemoryNM4x4<"sw", GPRNM4Opnd, mem_nm2s2, store, addruimm2s2, II_SW>, + LSMem4x4_Enc<0b11101>; + def SWPC_NM : StorePCBase, Op48_Enc<0b01011>; def LWPC_NM : LoadPCBase, Op48_Enc<0b01111>; From 68d5668690bd898fa50cb503d856ee2206acffad Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 2 Jan 2023 18:17:28 +0530 Subject: [PATCH 051/123] Add LI[16] instruction and encoding --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 5 +++ .../Mips/Disassembler/MipsDisassembler.cpp | 14 ++++++++ llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 34 +++++++++++++++++-- 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 5bd84a9c845ca..0bfb4bfc6165b 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1403,6 +1403,11 @@ class MipsOperand : public MCParsedAsmOperand { getConstantImm() <= Top; } + template bool isConstantSImmRange() const { + return isConstantImm() && getConstantImm() >= Bottom && + getConstantImm() <= Top; + } + template bool isConstantNegImmRange() const { return isConstantImm() && getConstantImm() >= -Bottom && getConstantImm() <= -Top; diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 35833642ced47..c07b6e0c366f4 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -614,6 +614,10 @@ static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeImmM1To126(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder); + static MCDisassembler *createMipsDisassembler( const Target &T, const MCSubtargetInfo &STI, @@ -2958,3 +2962,13 @@ static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, return MCDisassembler::Success; } + +static DecodeStatus DecodeImmM1To126(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder) { + if (Value == 127) + Inst.addOperand(MCOperand::createImm(-1)); + else + Inst.addOperand(MCOperand::createImm(Value)); + return MCDisassembler::Success; +} diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index ae9dc900bdb30..991d671100496 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -122,7 +122,7 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, - LAGPB_NM, LUI_NM, + LAGPB_NM, LUI_NM, LI16_NM, LSA_NM, MOVEP_NM, MOVE16_NM, MOD_NM, MODU_NM, MOVEPREV_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index a5c532fccf316..2b54a8b9bb67d 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -53,6 +53,10 @@ def imm32SExt12OrZExt16 : IntImmLeaf(Imm.getSExtValue() def imm32SExt20s12 : IntImmLeaf(Imm.getSExtValue()) && (Imm.getZExtValue() % 4096 == 0); }]>; +// Immediate range for 16-bit load immediate +def imm7M1To126 : IntImmLeaf= -1 && Imm.getSExtValue() < 127); +}]>; class ConstantSImmRangeAsmOperandClass Supers = []> @@ -73,8 +77,16 @@ class NegImmAsmOperandClass Supers = []> let DiagnosticType = "SImm" # Bits; } +class Imm7AsmOperandClass : AsmOperandClass { + let Name = "UImm7N1"; + let RenderMethod = "addSImmOperands<8>"; + let PredicateMethod = "isConstantSImmRange<-1,126>"; +} + def UImm12AsmOperandClass : UImmAsmOperandClass<12, []>; def UImm5AsmOperandClass : UImmAsmOperandClass<5, [UImm12AsmOperandClass]>; +def Imm7AsmOperand : Imm7AsmOperandClass; + def SImm12AsmOperandClass : SImmAsmOperandClass<12, []>; def NImm12AsmOperandClass : NegImmAsmOperandClass<12, []>; def NaImm12AsmOperandClass : ConstantSImmRangeAsmOperandClass<4095, 1, []>; @@ -154,6 +166,10 @@ def uimm16_nm : Operand { let PrintMethod = "printUImm<16>"; let ParserMatchClass = !cast("SImm16AsmOperandClass"); } +def nimm7_nm : Operand { + let ParserMatchClass = !cast("Imm7AsmOperand"); + let DecoderMethod = "DecodeImmM1To126"; +} def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; @@ -537,8 +553,6 @@ class _Pool_P16_ADDU psel> : _Pool_P16<0b10100> { // TODO BNEZC_16 : _Pool_P16<0b10110> -// TODO LI16 : _Pool_P16<0b11000> - class _Pool_P16_BR psel> : _Pool_P16<0b11010> { let Inst{3...0} = psel; } @@ -941,6 +955,14 @@ class LSMem4x4_Enc isel> : _Pool_P16 let Inst{8} = offset{2}; } +class LI16_Enc isel> : _Pool_P16 +{ + bits<3> rt; + bits<7> eu; + let Inst{9...7} = rt; + let Inst{6...0} = eu; +} + class LoadMemoryNM; +class LoadImmediateNM : + InstNM<(outs RO:$rt), (ins Od:$eu), + !strconcat(opstr, "\t$rt, $eu"), + [(set RO:$rt, imm_type:$eu)]>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -1320,6 +1348,8 @@ def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>; def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { +def LI16_NM : LoadImmediateNM<"li", GPRNM3Opnd, nimm7_nm, imm7M1To126>, + LI16_Enc<0b11000>; def Li_NM : LoadAddressAbsNM<"li", GPRNM32Opnd, sym32_abs_nm, addrpcrel>, Op48_Enc<0b00000>; def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM32Opnd, sym32_gp_nm, From 0c00a3b4efc21675855a6f900376165c8ff0ae4e Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 2 Jan 2023 21:50:41 +0530 Subject: [PATCH 052/123] Add ANDI[16] encoding and decoding --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 7 ++++ .../Mips/Disassembler/MipsDisassembler.cpp | 16 +++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 16 +++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 4 +++ llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 35 +++++++++++++++++-- 6 files changed, 77 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 0bfb4bfc6165b..88494a49e2f37 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1408,6 +1408,13 @@ class MipsOperand : public MCParsedAsmOperand { getConstantImm() <= Top; } + bool isConstantUImmMask() const { + return (isConstantImm() && + ((getConstantImm() >= 0 && getConstantImm() < 11) || + (getConstantImm() == 0xff) || (getConstantImm() == 0xffff) || + (getConstantImm() == 0xe) || (getConstantImm() == 0xf))); + } + template bool isConstantNegImmRange() const { return isConstantImm() && getConstantImm() >= -Bottom && getConstantImm() <= -Top; diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index c07b6e0c366f4..4d26862f761b3 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -618,6 +618,10 @@ static DecodeStatus DecodeImmM1To126(MCInst &Inst, unsigned Value, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeUImm4Mask(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder); + static MCDisassembler *createMipsDisassembler( const Target &T, const MCSubtargetInfo &STI, @@ -2972,3 +2976,15 @@ static DecodeStatus DecodeImmM1To126(MCInst &Inst, unsigned Value, Inst.addOperand(MCOperand::createImm(Value)); return MCDisassembler::Success; } + +static DecodeStatus DecodeUImm4Mask(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder) { + if (Value == 12) + Inst.addOperand(MCOperand::createImm(0xff)); + else if (Value == 13) + Inst.addOperand(MCOperand::createImm(0xffff)); + else + Inst.addOperand(MCOperand::createImm(Value)); + return MCDisassembler::Success; +} diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 2d96b86d1efa8..71214d17f51cb 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1398,6 +1398,22 @@ MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, llvm_unreachable("Unexpected value"); } +unsigned +MipsMCCodeEmitter::getUImm4MaskEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + assert(MI.getOperand(OpNo).isImm()); + const MCOperand &MO = MI.getOperand(OpNo); + unsigned Value = MO.getImm(); + switch (Value) { + case 0xff: return 12; + case 0xffff: return 13; + default: return Value; + } + llvm_unreachable("Unexpected value"); +} + + unsigned MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index f5b1dfe974b6b..9279aace9ca62 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -301,6 +301,10 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getUImm4MaskEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 991d671100496..ce8ec16dd4b12 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -119,7 +119,7 @@ def : InstRW<[GenericWriteALU], (instrs ADDIUPC_MMR6, ADDIU_MMR6, ADDU16_MMR6, def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ADDiu_NM, ADDIU48_NM, ADDIUPC48_NM, - ALUIPC_NM, AND_NM, AND16_NM, ANDI_NM, + ALUIPC_NM, AND_NM, AND16_NM, ANDI16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, LAGPB_NM, LUI_NM, LI16_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 2b54a8b9bb67d..98bfa4d09aad1 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -58,6 +58,13 @@ def imm7M1To126 : IntImmLeaf= -1 && Imm.getSExtValue() < 127); }]>; +// Immediate range for 16-bit AND immediate +def imm4Mask : IntImmLeaf= 0 && Imm.getZExtValue() < 11) || + (Imm.getZExtValue() == 0xff) || (Imm.getZExtValue() == 0xffff) || + (Imm.getZExtValue() == 0xe) || (Imm.getZExtValue() == 0xf)); +}]>; + class ConstantSImmRangeAsmOperandClass Supers = []> : AsmOperandClass { @@ -83,9 +90,16 @@ class Imm7AsmOperandClass : AsmOperandClass { let PredicateMethod = "isConstantSImmRange<-1,126>"; } +class UImm4AsmOperandClass : AsmOperandClass { + let Name = "UImm4Mask"; + let RenderMethod = "addUImmOperands<16>"; + let PredicateMethod = "isConstantUImmMask"; +} + def UImm12AsmOperandClass : UImmAsmOperandClass<12, []>; def UImm5AsmOperandClass : UImmAsmOperandClass<5, [UImm12AsmOperandClass]>; def Imm7AsmOperand : Imm7AsmOperandClass; +def UImm4AsmOperand : UImm4AsmOperandClass; def SImm12AsmOperandClass : SImmAsmOperandClass<12, []>; def NImm12AsmOperandClass : NegImmAsmOperandClass<12, []>; @@ -170,6 +184,12 @@ def nimm7_nm : Operand { let ParserMatchClass = !cast("Imm7AsmOperand"); let DecoderMethod = "DecodeImmM1To126"; } +def uimm4_nm : Operand { + let EncoderMethod = "getUImm4MaskEncoding"; + let PrintMethod = "printUImm<16>"; + let ParserMatchClass = !cast("UImm4AsmOperand"); + let DecoderMethod = "DecodeUImm4Mask"; +} def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; @@ -565,8 +585,6 @@ class _Pool_P16_SYSCALL psel> : _Pool_P16_RI<0b01> { let Inst{2} = psel; } -// TODO ANDI_16 : _Pool_P16<0b11100> - class _Pool_P_RI psel> : _Pool_P_ADDIU<0b00000> { let Inst{20...19} = psel; } @@ -1361,6 +1379,19 @@ def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPRNM32Opnd>, Op48_Enc<0b00011>; } +class ANDI16_Enc isel> : _Pool_P16 +{ + bits<3> rt; + bits<3> rs; + bits<4> imm; + let Inst{9...7} = rt; + let Inst{6...4} = rs; + let Inst{3...0} = imm; +} + +def ANDI16_NM : ArithLogicINM<"andi", uimm4_nm, GPRNM3Opnd, + imm4Mask, add>, ANDI16_Enc<0b11100>; + // Arithmetic and logical instructions with 2 register operands and immediate. class LoadUpperINM Date: Mon, 2 Jan 2023 23:12:37 +0530 Subject: [PATCH 053/123] Add BRSC and BALRSC encoding and decoding --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 5 ++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 47 ++++++++++++++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index ce8ec16dd4b12..146658aa2acf5 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -465,14 +465,15 @@ def : InstRW<[GenericWriteJump], (instrs JRC_NM, BC_NM, BEQC_NM, BGEC_NM, BGEUC_ BNEC_NM, BLTC_NM, BLTUC_NM, BEQZC_NM, BNEZC_NM, BEQIC_NM, BGEIC_NM, BLTIC_NM, BNEIC_NM, BGEIUC_NM, BLTIUC_NM, BBNEZC_NM, - BBEQZC_NM, BC16_NM, BALC16_NM)>; + BBEQZC_NM, BC16_NM, BALC16_NM, + BRSC_NM)>; def : InstRW<[GenericWriteJump], (instrs PseudoReturnNM, PseudoIndirectBranchNM, TAILCALL_NM, TAILCALLREG_NM)>; def : InstRW<[GenericWriteJumpAndLink], (instrs BALC_NM, MOVEBALC_NM, JALRC_NM, - JALRCPseudo)>; + JALRCPseudo, BALRSC_NM)>; // COP0 Pipeline // ============= diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 98bfa4d09aad1..fb7bacb07412c 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -442,9 +442,6 @@ class _Pool_P_BALRSC psel> : _Pool_P_J<0b1000> { let Inst{25...21} = psel; } -// TODO BRSC : _Pool_P_BALRSC<0b00000> -// TODO BALRSC : _Pool_P_BALRSC - class _Pool_P_SHIFT psel> : _Pool_P_U12<0b1100> { let Inst{8...5} = psel; bits<5> shift; @@ -981,6 +978,28 @@ class LI16_Enc isel> : _Pool_P16 let Inst{6...0} = eu; } +class IndirectBranch32_Enc : _Pool_P_J<0b1000> +{ + bits<5> rs; + let Inst{25...21} = 0b00000; + let Inst{20...16} = rs; +} + +class IndirectBranch16_Enc isel> : _Pool_P16_BR<0b0000> +{ + bits<5> rs; + let Inst{9...5} = rs; + let Inst{4} = isel; +} + +class IndirectCallNM_Enc isel> : _Pool_P_J +{ + bits<5> rt; + bits<5> rs; + let Inst{25...21} = rt; + let Inst{20...16} = rs; +} + class LoadMemoryNM : + InstNM<(outs RA:$rt), (ins RO:$rs), !strconcat(opstr, "\t$rt, $rs"), + []> { + let isCall = 1; + let isCTI = 1; +} + class MoveBalcBase : InstNM<(outs GPRNM32Opnd:$rd), (ins GPRNM32Opnd:$rt, calltarget25_nm:$addr), "move.balc\t$rd, $rt, $addr", []>, InstSize32 { @@ -1112,7 +1139,7 @@ class MoveBalcBase : InstNM<(outs GPRNM32Opnd:$rd), class IndirectBranchNM: InstNM<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), - [(operator RO:$rs)]>, _Pool_P16_BR<0b0000> { + [(operator RO:$rs)]> { let isTerminator = 1; let isBarrier = 1; let isCTI = 1; @@ -1361,7 +1388,7 @@ def AND16_NM : ArithLogicR16_Desc<"and", GPRNM3Opnd>, def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM3Opnd>, ArithLogicR16_Enc<0b11>; -def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>; +def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>, IndirectBranch16_Enc<0>; def MOVEBALC_NM : MoveBalcBase; @@ -1445,10 +1472,11 @@ def PseudoIndirectBranchNM : bit isCTI = 1; } + let hasPostISelHook = 1, isCall = 1, isCTI = 1, Defs = [RA_NM] in { - def JALRC_NM : InstNM<(outs GPRNM32Opnd:$rd), (ins GPRNM32Opnd:$rs), - "jalrc\t$rd, $rs", []>, InstSize32; + def JALRC_NM : IndirectCallNM<"jalrc", GPRNM32Opnd, GPRNM32Opnd>, + IndirectCallNM_Enc<0b0000>; def JALRCPseudo : PseudoInstNM<(outs), (ins GPRNM32Opnd:$rs), [(MipsJmpLink GPRNM32Opnd:$rs)]>, PseudoInstExpansion<(JALRC_NM RA_NM, GPRNM32Opnd:$rs)>; @@ -1684,6 +1712,11 @@ def BGEIUC_NM : CBranchImmNM<"bgeiuc", brtarget11_nm, setuge, GPRNM32Opnd, uimm7 def BLTIUC_NM : CBranchImmNM<"bltiuc", brtarget11_nm, setult, GPRNM32Opnd, uimm7, immZExt7>, BRI_Enc<0b111>; + + +def BRSC_NM : IndirectBranchNM<"brsc", GPRNM32Opnd>, IndirectBranch32_Enc; +def BALRSC_NM : IndirectCallNM<"balrsc", GPRNM32NZOpnd, GPRNM32Opnd>, IndirectCallNM_Enc<0b1000>; + // Bit-test branches let hasNoSchedulingInfo = 1, hasDelaySlot = 0 in { From 60754029564878107e8e06c9c731d652eab49955 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 2 Jan 2023 23:20:58 +0530 Subject: [PATCH 054/123] Add encodings for MOVN/MOVZ --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index fb7bacb07412c..85cbac2b30ef4 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -600,6 +600,11 @@ class _Pool_P_TRAP isel> : _Pool_POOL32A0_0<0b000000> let Inst{10} = isel; } +class _Pool_P_CMOVE isel> : _Pool_POOL32A0_0<0b100010> +{ + let Inst{10} = isel; +} + class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { let Inst{5...3} = psel; } @@ -2038,18 +2043,28 @@ def : NMPat<(atomic_store_8 addr:$a, GPR32:$v), (SB_NM GPR32:$v, addr:$a)>; def : NMPat<(atomic_store_16 addr:$a, GPR32:$v), (SH_NM GPR32:$v, addr:$a)>; def : NMPat<(atomic_store_32 addr:$a, GPR32:$v), (SW_NM GPR32:$v, addr:$a)>; +class CondMove_Enc isel> : _Pool_P_CMOVE +{ + bits<5> rd; + bits<5> rs; + bits<5> rt; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...11} = rd; +} + // Conditional Moves def MOVZ_NM : InstNM<(outs GPRNM32Opnd:$rd), (ins GPRNM32Opnd:$rs, GPRNM32Opnd:$rt, GPRNM32Opnd:$F), "movz\t$rd, $rs, $rt", - []>, InstSize32 { + []>, CondMove_Enc<0b0> { let Constraints = "$F = $rd"; } def MOVN_NM : InstNM<(outs GPRNM32Opnd:$rd), (ins GPRNM32Opnd:$rs, GPRNM32Opnd:$rt, GPRNM32Opnd:$F), "movn\t$rd, $rs, $rt", - []>, InstSize32 { + []>, CondMove_Enc<0b1> { let Constraints = "$F = $rd"; } From c4e5aa329fb39dd5e21110c1a920aba58a3c95b8 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 3 Jan 2023 01:44:25 +0530 Subject: [PATCH 055/123] Add encodings for BEQC[16] and BNEC[16] --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 16 ++++++++++++ llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 25 +++++++++++++++---- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 88494a49e2f37..32fd60f732f12 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -522,6 +522,8 @@ class MipsAsmParser : public MCTargetAsmParser { Match_RequiresPosSizeUImm6, Match_RequiresDstRegPair, Match_RequiresSrcRegPair, + Match_RequiresFirstOpLT, + Match_RequiresFirstOpGE, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "MipsGenAsmMatcher.inc" #undef GET_OPERAND_DIAGNOSTIC_TYPES @@ -6216,6 +6218,14 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { if (Inst.getOperand(3).getReg() != Inst.getOperand(2).getReg() + 1) return Match_RequiresSrcRegPair; return Match_Success; + case Mips::BEQC16_NM: + if (Inst.getOperand(0).getReg() >= Inst.getOperand(1).getReg()) + return Match_RequiresFirstOpLT; + return Match_Success; + case Mips::BNEC16_NM: + if (Inst.getOperand(0).getReg() < Inst.getOperand(1).getReg()) + return Match_RequiresFirstOpGE; + return Match_Success; } uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags; @@ -6289,6 +6299,12 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(IDLoc, "destination registers must be in sequence"); case Match_RequiresSrcRegPair: return Error(IDLoc, "source registers must be in sequence"); + case Match_RequiresFirstOpLT: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "first register operand(rs) must be less than second(rt)"); + case Match_RequiresFirstOpGE: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "first register operand(rs) must not be less than second(rt)"); case Match_NoFCCRegisterForCurrentISA: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "non-zero fcc register doesn't exist in current ISA level"); diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 146658aa2acf5..8adfecdc32f8d 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -466,7 +466,7 @@ def : InstRW<[GenericWriteJump], (instrs JRC_NM, BC_NM, BEQC_NM, BGEC_NM, BGEUC_ BNEZC_NM, BEQIC_NM, BGEIC_NM, BLTIC_NM, BNEIC_NM, BGEIUC_NM, BLTIUC_NM, BBNEZC_NM, BBEQZC_NM, BC16_NM, BALC16_NM, - BRSC_NM)>; + BRSC_NM, BEQC16_NM, BNEC16_NM)>; def : InstRW<[GenericWriteJump], (instrs PseudoReturnNM, PseudoIndirectBranchNM, TAILCALL_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 85cbac2b30ef4..2c3ba2d19fa2b 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -306,6 +306,13 @@ foreach I = {4, 7, 10, 11, 14, 25} in let ParserMatchClass = NMJumpTargetAsmOperand; } +def brtarget4s1_nm : Operand { + let EncoderMethod = "getBranchTarget4OpValueNM"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTargetNM"; + let ParserMatchClass = NMJumpTargetAsmOperand; +} + foreach I = {10, 25} in def calltarget # I # _nm : Operand { let EncoderMethod = "getBranchTarget" # I # "OpValueNM"; @@ -562,14 +569,10 @@ class _Pool_P16_A2 psel> : _Pool_P16<0b10000> { let Inst{3} = psel; } -//TODO BEQZC_16 : _Pool_P16<0b10010> - class _Pool_P16_ADDU psel> : _Pool_P16<0b10100> { let Inst{0} = psel; } -// TODO BNEZC_16 : _Pool_P16<0b10110> - class _Pool_P16_BR psel> : _Pool_P16<0b11010> { let Inst{3...0} = psel; } @@ -1684,16 +1687,28 @@ def BALC16_NM : CallNM<"balc", MipsJmpLink, calltarget10_nm>, BC16_Enc<0b00110>; def : NMPat<(MipsJmpLink (i32 texternalsym:$dst)), (BALC_NM texternalsym:$dst)>; +class B4_Enc : _Pool_P16<0b11010> { + bits<3> rs; + bits<3> rt; + bits<4> offset; + let Inst{9...7} = rt; + let Inst{6...4} = rs; + let Inst{3...0} = offset; +} def BEQC_NM : CBranchNM<"beqc", brtarget14_nm, seteq, GPRNM32Opnd>, B14_Enc<0b000>; -def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPRNM32Opnd>, +def BEQC16_NM : CBranchNM<"beqc16", brtarget4s1_nm, seteq, GPRNM3Opnd>, + B4_Enc; +def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPRNM3Opnd>, B14_Enc<0b010>; def BGEUC_NM : CBranchNM<"bgeuc", brtarget14_nm, setuge, GPRNM32Opnd>, B14_Enc<0b011>; def BNEC_NM : CBranchNM<"bnec", brtarget14_nm, setne, GPRNM32Opnd>, B14_Enc<0b100>; +def BNEC16_NM : CBranchNM<"bnec16", brtarget4s1_nm, setne, GPRNM3Opnd>, + B4_Enc; def BLTC_NM : CBranchNM<"bltc", brtarget14_nm, setlt, GPRNM32Opnd>, B14_Enc<0b110>; def BLTUC_NM : CBranchNM<"bltuc", brtarget14_nm, setult, GPRNM32Opnd>, From 425e903f27fd29f7c9f66103bb3a1012949fde46 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 3 Jan 2023 13:11:27 +0530 Subject: [PATCH 056/123] Add encoding/decoding for SLL[16] and SRL[16] --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 4 ++ .../Mips/Disassembler/MipsDisassembler.cpp | 14 +++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 14 +++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 4 ++ llvm/lib/Target/Mips/MipsScheduleGeneric.td | 3 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 42 +++++++++++++++---- 6 files changed, 73 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 32fd60f732f12..7f34137e2b162 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1538,6 +1538,10 @@ class MipsOperand : public MCParsedAsmOperand { && (getMemBase()->getGPR32Reg() == Mips::GP); } + bool isConstantUImm3Shift() const { + return (isConstantImm() && getConstantImm() > 0 && getConstantImm() <= 8); + } + MipsOperand *getMemBase() const { assert((Kind == k_Memory) && "Invalid access!"); return Mem.Base; diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 4d26862f761b3..8b72182a2b107 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -622,6 +622,10 @@ static DecodeStatus DecodeUImm4Mask(MCInst &Inst, unsigned Value, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeUImm3Shift(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder); + static MCDisassembler *createMipsDisassembler( const Target &T, const MCSubtargetInfo &STI, @@ -2988,3 +2992,13 @@ static DecodeStatus DecodeUImm4Mask(MCInst &Inst, unsigned Value, Inst.addOperand(MCOperand::createImm(Value)); return MCDisassembler::Success; } + +static DecodeStatus DecodeUImm3Shift(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder) { + if (Value == 0) + Inst.addOperand(MCOperand::createImm(8)); + else + Inst.addOperand(MCOperand::createImm(Value)); + return MCDisassembler::Success; +} diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 71214d17f51cb..46b016dd6db52 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1546,4 +1546,18 @@ MipsMCCodeEmitter::getGPRNM4x4Reg(const MCInst &MI, unsigned OpNo, } } +unsigned +MipsMCCodeEmitter::getUImm3ShiftEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + assert(MI.getOperand(OpNo).isImm()); + const MCOperand &MO = MI.getOperand(OpNo); + unsigned Value = MO.getImm(); + if (Value == 8) + return 0; + else + return Value; + llvm_unreachable("Unexpected value"); +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 9279aace9ca62..a4c94407101c5 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -347,6 +347,10 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getUImm3ShiftEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + private: void LowerCompactBranch(MCInst& Inst) const; }; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 8adfecdc32f8d..0a3157dd744ec 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -130,7 +130,8 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ROTR_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, SLLV_NM, SLT_NM, SLTI_NM, SLTIU_NM, SLTU_NM, SRAV_NM, SRA_NM, SRLV_NM, SRL_NM, SUB_NM, - SUBu_NM, SUBu16_NM, XOR_NM, XOR16_NM, XORI_NM)>; + SUBu_NM, SUBu16_NM, XOR_NM, XOR16_NM, XORI_NM, + SLL16_NM, SRL16_NM)>; // MIPS64 // ====== diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 2c3ba2d19fa2b..3c00606a720cd 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -37,6 +37,8 @@ def imm32ZExt12ANDI : IntImmLeaf(Imm.getZExtValue()) || Imm.getZExtValue() == 65535; }]>; def imm32ZExt5 : IntImmLeaf(Imm.getZExtValue()); }]>; +def imm32ZExt3 : IntImmLeaf 0 && + Imm.getZExtValue() <= 8;}]>; def imm32SExt12 : IntImmLeaf(Imm.getSExtValue()); }]>; def imm32Neg12 : IntImmLeaf(Imm.getSExtValue()) && Imm.getSExtValue() < 0; }]>; // True if (N + 1) fits in 12-bit field. @@ -96,10 +98,17 @@ class UImm4AsmOperandClass : AsmOperandClass { let PredicateMethod = "isConstantUImmMask"; } +class UImm3ShiftAsmOperandClass : AsmOperandClass { + let Name = "UImm3Shift"; + let RenderMethod = "addUImmOperands<4>"; + let PredicateMethod = "isConstantUImm3Shift"; +} + def UImm12AsmOperandClass : UImmAsmOperandClass<12, []>; def UImm5AsmOperandClass : UImmAsmOperandClass<5, [UImm12AsmOperandClass]>; def Imm7AsmOperand : Imm7AsmOperandClass; def UImm4AsmOperand : UImm4AsmOperandClass; +def UImm3ShiftAsmOperand : UImm3ShiftAsmOperandClass; def SImm12AsmOperandClass : SImmAsmOperandClass<12, []>; def NImm12AsmOperandClass : NegImmAsmOperandClass<12, []>; @@ -190,6 +199,12 @@ def uimm4_nm : Operand { let ParserMatchClass = !cast("UImm4AsmOperand"); let DecoderMethod = "DecodeUImm4Mask"; } +def uimm3shift_nm : Operand { + let EncoderMethod = "getUImm3ShiftEncoding"; + let PrintMethod = "printUImm<4>"; + let ParserMatchClass = !cast("UImm3ShiftAsmOperand"); + let DecoderMethod = "DecodeUImm3Shift"; +} def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; @@ -534,8 +549,8 @@ class _Pool_P16_SR psel> : _Pool_P16<0b00011> { let Inst{8} = psel; } -class _Pool_P16_SHIFT psel> : _Pool_P16<0b00100> { - let Inst{3} = psel; +class _Pool_P16_SHIFT isel> : _Pool_P16<0b00100> { + let Inst{3} = isel; } class _Pool_P16_4X4 psel> : _Pool_P16<0b00111> { @@ -760,7 +775,7 @@ class CondLogicI32_Enc psel> : _Pool_P_U12 { let Inst{11...0} = imm; } -class ShiftI32_Desc : ArithLogicINM; @@ -774,6 +789,15 @@ class ShiftI32_Enc psel> : _Pool_P_SHIFT { let Inst{4...0} = imm; } +class ShiftI16_Enc isel> : _Pool_P16_SHIFT { + bits<3> rt; + bits<3> rs; + bits<3> imm; + let Inst{9...7} = rt; + let Inst{6...4} = rs; + let Inst{2...0} = imm; +} + class ExtBaseNM : InstNM<(outs RO:$rt), (ins RO:$rs, uimm5:$pos, uimm5_plus1:$size), "ext\t$rt, $rs, $pos, $size", @@ -1352,13 +1376,17 @@ def SEQI_NM : CondLogicI32_Desc<"seqi", uimm12_nm, GPRNM32Opnd, imm32ZExt12, se CondLogicI32_Enc<0b0110>; // P.SHIFT pool of instructions -def SLL_NM : ShiftI32_Desc<"sll", uimm5_nm, GPRNM32Opnd, imm32ZExt5, shl>, +def SLL_NM : ShiftI_Desc<"sll", uimm5_nm, GPRNM32Opnd, imm32ZExt5, shl>, ShiftI32_Enc<0b0000>; -def SRL_NM : ShiftI32_Desc<"srl", uimm5_nm, GPRNM32Opnd, imm32ZExt5, srl>, +def SLL16_NM : ShiftI_Desc<"sll", uimm3shift_nm, GPRNM3Opnd, imm32ZExt3, shl>, + ShiftI16_Enc<0b0>; +def SRL_NM : ShiftI_Desc<"srl", uimm5_nm, GPRNM32Opnd, imm32ZExt5, srl>, ShiftI32_Enc<0b0010>; -def SRA_NM : ShiftI32_Desc<"sra", uimm5_nm, GPRNM32Opnd, imm32ZExt5, sra>, +def SRL16_NM : ShiftI_Desc<"srl", uimm3shift_nm, GPRNM3Opnd, imm32ZExt3, srl>, + ShiftI16_Enc<0b1>; +def SRA_NM : ShiftI_Desc<"sra", uimm5_nm, GPRNM32Opnd, imm32ZExt5, sra>, ShiftI32_Enc<0b0100>; -def ROTR_NM : ShiftI32_Desc<"rotr", uimm5_nm, GPRNM32Opnd, imm32ZExt5, rotr>, +def ROTR_NM : ShiftI_Desc<"rotr", uimm5_nm, GPRNM32Opnd, imm32ZExt5, rotr>, ShiftI32_Enc<0b0110>; def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; From 090d6a873fe327755fe2bd066afaa82c5d09065b Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 3 Jan 2023 15:02:06 +0530 Subject: [PATCH 057/123] Add encodings for CLO, CLZ, SEB, SEH, LSA --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 55 +++++++++++++++++------ 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 3c00606a720cd..eb049605078e7 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -627,6 +627,11 @@ class _Pool_POOL32A7 psel> : _Pool_P32A<0b111> { let Inst{5...3} = psel; } +class _Pool_POOL32Axf_4 isel> : _Pool_POOL32A7<0b111> { + let Inst{15...9} = isel; + let Inst{8...6} = 0b100; +} + class _Pool_PP_LSX isel> : _Pool_POOL32A7<0b000> { let Inst{6} = scaled; let Inst{10...7} = isel; @@ -693,6 +698,20 @@ class ArithLogicR16_Enc isel>: _Pool_POOL16C_00 { let Inst{6...4} = rs; } +class CLZO_Enc isel>: _Pool_POOL32Axf_4 { + bits<5> rs; + bits<5> rt; + let Inst{25...21} = rt; + let Inst{20...16} = rs; +} + +class LogicU32_Enc isel>: _Pool_POOL32A0_0 { + bits<5> rs; + bits<5> rt; + let Inst{25...21} = rt; + let Inst{20...16} = rs; +} + // 16-bit arithmetic instructions with 2 register operands, POOL16C_0 class AddSubR16_Desc: @@ -1254,22 +1273,32 @@ class ReadHardwareNM : } class SignExtInRegNM : - InstNM<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), - [(set RO:$rd, (sext_inreg RO:$rt, vt))]>, InstSize32; + InstNM<(outs RO:$rt), (ins RO:$rs), !strconcat(opstr, "\t$rt, $rs"), + [(set RO:$rt, (sext_inreg RO:$rs, vt))]>; class LoadScaledAddressNM : InstNM<(outs RO:$rd), (ins RO:$rs, RO:$rt, uimm2:$shift), !strconcat(opstr, "\t$rd, $rs, $rt, $shift"), - [(set RO:$rd, (add (shl RO:$rs, immZExt2:$shift), RO:$rt))]>, - InstSize32; + [(set RO:$rd, (add (shl RO:$rs, immZExt2:$shift), RO:$rt))]>; + +class LoadScaledAddress_Enc: _Pool_POOL32A7<0b001> { + bits<5> rd; + bits<5> rs; + bits<5> rt; + bits<2> shift; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...11} = rd; + let Inst{10...9} = shift; +} class CountLeading0NM: - InstNM<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz RO:$rs))]>, InstSize32; + InstNM<(outs RO:$rt), (ins RO:$rs), !strconcat(opstr, "\t$rt, $rs"), + [(set RO:$rt, (ctlz RO:$rs))]>; class CountLeading1NM: - InstNM<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz (not RO:$rs)))]>, InstSize32; + InstNM<(outs RO:$rt), (ins RO:$rs), !strconcat(opstr, "\t$rt, $rs"), + [(set RO:$rt, (ctlz (not RO:$rs)))]>; class ReverseNM: InstNM<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), @@ -1400,13 +1429,13 @@ def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPRNM32Opnd, def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPRNM32Opnd, sym32_pc_nm, addrpcrel>, Op48_Enc<0b00011>; -def LSA_NM : LoadScaledAddressNM<"lsa", GPRNM32Opnd>; +def LSA_NM : LoadScaledAddressNM<"lsa", GPRNM32Opnd>, LoadScaledAddress_Enc; -def SEB_NM : SignExtInRegNM<"seb", i8, GPRNM32Opnd>; -def SEH_NM : SignExtInRegNM<"seh", i16, GPRNM32Opnd>; +def SEB_NM : SignExtInRegNM<"seb", i8, GPRNM32Opnd>, LogicU32_Enc<0b000001>; +def SEH_NM : SignExtInRegNM<"seh", i16, GPRNM32Opnd>, LogicU32_Enc<0b000101>; -def CLZ_NM : CountLeading0NM<"clz", GPRNM32Opnd>; -def CLO_NM : CountLeading1NM<"clo", GPRNM32Opnd>; +def CLZ_NM : CountLeading0NM<"clz", GPRNM32Opnd>, CLZO_Enc<0b0101101>; +def CLO_NM : CountLeading1NM<"clo", GPRNM32Opnd>, CLZO_Enc<0b0100101>; def BITREVW_NM : ReverseNM<"bitrevw", GPRNM32Opnd, bitreverse>; def BYTEREVW_NM : ReverseNM<"byterevw", GPRNM32Opnd, bswap>; From ca4d9918a968e8c38e6f54ae400250e815cd6cd5 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 3 Jan 2023 18:27:08 +0530 Subject: [PATCH 058/123] Add encodings for DI/EI/ERET/ERETNC/DERET/NOP32/PAUSE/EHB/SYNC --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 7 ++++ llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 46 +++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 0a3157dd744ec..9fa341cb35b0a 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -432,6 +432,8 @@ def : InstRW<[GenericWriteTrap], (instrs BREAK16_MMR6, BREAK_MMR6, SDBBP_MMR6, def : InstRW<[GenericWriteTrap], (instrs TEQ_NM, TNE_NM)>; +def : InstRW<[GenericWriteJump], (instrs ERET_NM, ERETNC_NM, DERET_NM)>; + // MIPS64 // ====== @@ -556,6 +558,11 @@ def : InstRW<[GenericWriteCOPOther], (instrs DMFC2, DMTC2)>; def : InstRW<[GenericWriteMove], (instrs CFC2_MM, CTC2_MM)>; +// nanoMIPS +// ============= + +def : InstRW<[GenericWriteCOP0], (instrs DI_NM, EI_NM)>; + // MIPS MT ASE - hasMT // ==================== diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index eb049605078e7..330d8361a2743 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -632,6 +632,19 @@ class _Pool_POOL32Axf_4 isel> : _Pool_POOL32A7<0b111> { let Inst{8...6} = 0b100; } +class _Pool_POOL32Axf_5 psel> : _Pool_POOL32A7<0b111> { + let Inst{8...6} = 0b101; + let Inst{15...14} = psel; +} + +class _Pool_POOL32Axf_5_group1 isel> : _Pool_POOL32Axf_5<0b01> { + let Inst{13...9} = isel; +} + +class _Pool_POOL32Axf_5_group3 isel> : _Pool_POOL32Axf_5<0b11> { + let Inst{13...9} = isel; +} + class _Pool_PP_LSX isel> : _Pool_POOL32A7<0b000> { let Inst{6} = scaled; let Inst{10...7} = isel; @@ -2178,3 +2191,36 @@ defm : MovzPats0NM, ISA_NANOMIPS; defm : MovzPats2NM; defm : MovnPats, ISA_NANOMIPS; + +class ToggleInterrupts_Enc isel> : _Pool_POOL32Axf_5_group1 { + bits<5> rt; + let Inst{25...21} = rt; +} + +def DI_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins), + "di\t$rt", []>, ToggleInterrupts_Enc<0b00011>; + +def EI_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins), + "ei\t$rt", []>, ToggleInterrupts_Enc<0b01011>; + +// Instruction with no operands +class MnemonicOnly: + InstNM<(outs), (ins), opstr, []>; + +def ERET_NM : MnemonicOnly<"eret">, _Pool_POOL32Axf_5_group3<0b11001> { + let Inst{16} = 0b0; +} + +def ERETNC_NM : MnemonicOnly<"eretnc">, _Pool_POOL32Axf_5_group3<0b11001> { + let Inst{16} = 0b1; +} + +def DERET_NM : MnemonicOnly<"deret">, _Pool_POOL32Axf_5_group3<0b10001>; + +def NOP_NM : MipsInstAlias<"nop", (SLL_NM ZERO_NM, ZERO_NM, 0)>; + +def EHB_NM : MipsInstAlias<"ehb", (SLL_NM ZERO_NM, ZERO_NM, 3)>; + +def PAUSE_NM : MipsInstAlias<"pause", (SLL_NM ZERO_NM, ZERO_NM, 5)>; + +def SYNC_NM : MipsInstAlias<"sync", (SLL_NM ZERO_NM, ZERO_NM, 6)>; From ebda43d445fd74cdb7a297631ee1f4cab52c94f9 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 3 Jan 2023 20:35:15 +0530 Subject: [PATCH 059/123] Add SDBBP, SIGRIE, BREAK & SYSCALL --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 3 +++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 3 ++- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 3 ++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 25 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 7f34137e2b162..e78a34d6299be 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -6400,6 +6400,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_SImm19_Lsl2: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected both 19-bit signed immediate and multiple of 4"); + case Match_UImm19: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 19-bit unsigned immediate"); case Match_UImm20_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 20-bit unsigned immediate"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 46b016dd6db52..bcec89dcc02eb 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -195,7 +195,8 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, // so we have to special check for them. const unsigned Opcode = TmpInst.getOpcode(); if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && - (Opcode != Mips::SLL_MM) && (Opcode != Mips::SLL_MMR6) && !Binary) + (Opcode != Mips::SLL_MM) && (Opcode != Mips::SLL_MMR6) && + (Opcode != Mips::SIGRIE_NM) && !Binary) llvm_unreachable("unimplemented opcode in encodeInstruction()"); int NewOpcode = -1; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 9fa341cb35b0a..a9b0e37added6 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -432,7 +432,8 @@ def : InstRW<[GenericWriteTrap], (instrs BREAK16_MMR6, BREAK_MMR6, SDBBP_MMR6, def : InstRW<[GenericWriteTrap], (instrs TEQ_NM, TNE_NM)>; -def : InstRW<[GenericWriteJump], (instrs ERET_NM, ERETNC_NM, DERET_NM)>; +def : InstRW<[GenericWriteJump], (instrs ERET_NM, ERETNC_NM, DERET_NM, + SIGRIE_NM, BREAK_NM, SDBBP_NM, SYSCALL_NM)>; // MIPS64 // ====== diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 330d8361a2743..d13b16cebcd99 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -206,6 +206,13 @@ def uimm3shift_nm : Operand { let DecoderMethod = "DecodeUImm3Shift"; } +def UImm19AsmOperand : UImmAsmOperandClass<19, []>; + +def uimm19_nm : Operand { + let PrintMethod = "printUImm<19>"; + let ParserMatchClass = UImm19AsmOperand; +} + def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; def mem_nm_gp7s2 : mem_generic { @@ -2224,3 +2231,21 @@ def EHB_NM : MipsInstAlias<"ehb", (SLL_NM ZERO_NM, ZERO_NM, 3)>; def PAUSE_NM : MipsInstAlias<"pause", (SLL_NM ZERO_NM, ZERO_NM, 5)>; def SYNC_NM : MipsInstAlias<"sync", (SLL_NM ZERO_NM, ZERO_NM, 6)>; + +class IntExcpFlow_Enc isel> : _Pool_P_RI +{ + bits<19> imm; + let Inst{18...0} = imm; +} + +def SIGRIE_NM : InstNM<(outs), (ins uimm19_nm:$imm), + "sigrie\t$imm", []>, IntExcpFlow_Enc<0b00>; + +def BREAK_NM : InstNM<(outs), (ins uimm19_nm:$imm), + "break\t$imm", []>, IntExcpFlow_Enc<0b10>; + +def SDBBP_NM : InstNM<(outs), (ins uimm19_nm:$imm), + "sdbbp\t$imm", []>, IntExcpFlow_Enc<0b11>; + +def SYSCALL_NM : InstNM<(outs), (ins uimm19_nm:$imm), + "syscall\t$imm", []>, IntExcpFlow_Enc<0b01>; From 38c81214b2c802a11ffa4e72e981c820592f26d1 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Wed, 4 Jan 2023 22:02:15 +0530 Subject: [PATCH 060/123] Fix SYSCALL[32] code encoding --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 3 --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 21 +++++++++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e78a34d6299be..7f34137e2b162 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -6400,9 +6400,6 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_SImm19_Lsl2: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected both 19-bit signed immediate and multiple of 4"); - case Match_UImm19: - return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), - "expected 19-bit unsigned immediate"); case Match_UImm20_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 20-bit unsigned immediate"); diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index d13b16cebcd99..b7f612116e207 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -206,13 +206,24 @@ def uimm3shift_nm : Operand { let DecoderMethod = "DecodeUImm3Shift"; } -def UImm19AsmOperand : UImmAsmOperandClass<19, []>; +class NMUImmAsmOperandClass Supers = []> : AsmOperandClass { + let Name = "NMUImm" # Bits; + let RenderMethod = "addUImmOperands<" # Bits # ">"; + let PredicateMethod = "isConstantUImm<" # Bits # ">"; + let SuperClasses = Supers; +} + +def UImm19AsmOperand : NMUImmAsmOperandClass<19>; +def UImm18AsmOperand : NMUImmAsmOperandClass<18>; def uimm19_nm : Operand { - let PrintMethod = "printUImm<19>"; let ParserMatchClass = UImm19AsmOperand; } +def uimm18_nm : Operand { + let ParserMatchClass = UImm18AsmOperand; +} + def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; def mem_nm_gp7s2 : mem_generic { @@ -2247,5 +2258,7 @@ def BREAK_NM : InstNM<(outs), (ins uimm19_nm:$imm), def SDBBP_NM : InstNM<(outs), (ins uimm19_nm:$imm), "sdbbp\t$imm", []>, IntExcpFlow_Enc<0b11>; -def SYSCALL_NM : InstNM<(outs), (ins uimm19_nm:$imm), - "syscall\t$imm", []>, IntExcpFlow_Enc<0b01>; +def SYSCALL_NM : InstNM<(outs), (ins uimm18_nm:$imm), + "syscall\t$imm", []>, IntExcpFlow_Enc<0b01> { + let Inst{18} = 0b0; +} From a3a6cf2001490b57cd9fad0f38f74607f017f166 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Wed, 4 Jan 2023 22:14:58 +0530 Subject: [PATCH 061/123] Add BREAK[16], SDBBP[16] & SYSCALL[16] --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 3 ++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 27 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index a9b0e37added6..bbb135f69a4f9 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -433,7 +433,8 @@ def : InstRW<[GenericWriteTrap], (instrs BREAK16_MMR6, BREAK_MMR6, SDBBP_MMR6, def : InstRW<[GenericWriteTrap], (instrs TEQ_NM, TNE_NM)>; def : InstRW<[GenericWriteJump], (instrs ERET_NM, ERETNC_NM, DERET_NM, - SIGRIE_NM, BREAK_NM, SDBBP_NM, SYSCALL_NM)>; + SIGRIE_NM, BREAK_NM, SDBBP_NM, SYSCALL_NM, + BREAK16_NM, SDBBP16_NM, SYSCALL16_NM)>; // MIPS64 // ====== diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index b7f612116e207..4551e089e07b1 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -215,6 +215,8 @@ class NMUImmAsmOperandClass Supers = []> : AsmOp def UImm19AsmOperand : NMUImmAsmOperandClass<19>; def UImm18AsmOperand : NMUImmAsmOperandClass<18>; +def UImm3AsmOperand : NMUImmAsmOperandClass<3, [UImm19AsmOperand]>; +def UImm2AsmOperand : NMUImmAsmOperandClass<2, [UImm18AsmOperand]>; def uimm19_nm : Operand { let ParserMatchClass = UImm19AsmOperand; @@ -224,6 +226,14 @@ def uimm18_nm : Operand { let ParserMatchClass = UImm18AsmOperand; } +def uimm3_nm : Operand { + let ParserMatchClass = UImm3AsmOperand; +} + +def uimm2_nm : Operand { + let ParserMatchClass = UImm2AsmOperand; +} + def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; def mem_nm_gp7s2 : mem_generic { @@ -2249,6 +2259,12 @@ class IntExcpFlow_Enc isel> : _Pool_P_RI let Inst{18...0} = imm; } +class IntExcpFlow16_Enc isel> : _Pool_P16_RI +{ + bits<3> imm; + let Inst{2...0} = imm; +} + def SIGRIE_NM : InstNM<(outs), (ins uimm19_nm:$imm), "sigrie\t$imm", []>, IntExcpFlow_Enc<0b00>; @@ -2262,3 +2278,14 @@ def SYSCALL_NM : InstNM<(outs), (ins uimm18_nm:$imm), "syscall\t$imm", []>, IntExcpFlow_Enc<0b01> { let Inst{18} = 0b0; } + +def BREAK16_NM : InstNM<(outs), (ins uimm3_nm:$imm), + "break\t$imm", []>, IntExcpFlow16_Enc<0b10>; + +def SDBBP16_NM : InstNM<(outs), (ins uimm3_nm:$imm), + "sdbbp\t$imm", []>, IntExcpFlow16_Enc<0b11>; + +def SYSCALL16_NM : InstNM<(outs), (ins uimm2_nm:$imm), + "syscall\t$imm", []>, IntExcpFlow16_Enc<0b01> { + let Inst{2} = 0b0; +} From de3b2d24dd0659dd37ec1790764f015cae2a446f Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Thu, 5 Jan 2023 18:32:32 +0530 Subject: [PATCH 062/123] Add WRPGPR, RDPGPR and encoding for RDHWR --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 28 ++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index bbb135f69a4f9..4fb995006562c 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -292,7 +292,7 @@ def : InstRW<[GenericWriteDIVU], (instrs DDIVU, DMODU)>; // ======== def : InstRW<[GenericWriteALU], (instrs MOVN_NM, MOVZ_NM)>; -def : InstRW<[GenericWriteMove], (instrs RDHWR_NM)>; +def : InstRW<[GenericWriteMove], (instrs RDHWR_NM, WRPGPR_NM, RDPGPR_NM)>; // CTISTD Pipeline // --------------- diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 4551e089e07b1..48db8ab1e77ec 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1309,9 +1309,7 @@ class UnalignedStore : InstNM<(outs CPURegOperand:$rt), (ins RO:$hs, uimm5:$sel), - "rdhwr\t$rt, $hs, $sel", []>, InstSize32 { - let isCodeGenOnly = 1; -} + "rdhwr\t$rt, $hs, $sel", []>; class SignExtInRegNM : InstNM<(outs RO:$rt), (ins RO:$rs), !strconcat(opstr, "\t$rt, $rs"), @@ -1550,7 +1548,16 @@ def ALUIPC_NM : RegImmNM<"aluipc", simm32s12_nm, GPRNM32Opnd, imm32SExt20s12>, L def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPRNM32Opnd>, InstSize32; -def RDHWR_NM : ReadHardwareNM; +def RDHWR_NM : ReadHardwareNM, + _Pool_POOL32A0_0<0b011100> { + bits<5> rt; + bits<5> hs; + bits<5> sel; + let Inst{25...21} = rt; + let Inst{20...16} = hs; + let Inst{15...11} = sel; +} + def ADJCALLSTACKDOWN_NM : AdjustStack; def ADJCALLSTACKUP_NM : AdjustStack; @@ -2289,3 +2296,16 @@ def SYSCALL16_NM : InstNM<(outs), (ins uimm2_nm:$imm), "syscall\t$imm", []>, IntExcpFlow16_Enc<0b01> { let Inst{2} = 0b0; } + +class ShadowRW_Enc isel>: _Pool_POOL32Axf_5_group3 { + bits<5> rs; + bits<5> rt; + let Inst{25...21} = rt; + let Inst{20...16} = rs; +} + +def WRPGPR_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), + "wrpgpr\t$rt,$rs", []>, ShadowRW_Enc<0b11000>; + +def RDPGPR_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), + "rdpgpr\t$rt,$rs", []>, ShadowRW_Enc<0b10000>; From 190b43c8b84bfa6f42ea7bf6b79750a88573e079 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 6 Jan 2023 10:25:11 +0530 Subject: [PATCH 063/123] Add ROTX, EXTW and SOV --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 8 +-- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 66 +++++++++++++++++---- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 4fb995006562c..4026b645fe2b4 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -121,15 +121,15 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ADDIUPC48_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, - DIV_NM, DIVU_NM, EXT_NM, INS_NM, LA_NM, Li_NM, - LAGPB_NM, LUI_NM, LI16_NM, + DIV_NM, DIVU_NM, EXT_NM, EXTW_NM, INS_NM, LA_NM, + Li_NM, LAGPB_NM, LUI_NM, LI16_NM, LSA_NM, MOVEP_NM, MOVE16_NM, MOD_NM, MODU_NM, MOVEPREV_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, NOT_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, - ROTR_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, + ROTR_NM, ROTX_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, SLLV_NM, SLT_NM, SLTI_NM, SLTIU_NM, SLTU_NM, - SRAV_NM, SRA_NM, SRLV_NM, SRL_NM, SUB_NM, + SOV_NM, SRAV_NM, SRA_NM, SRLV_NM, SRL_NM, SUB_NM, SUBu_NM, SUBu16_NM, XOR_NM, XOR16_NM, XORI_NM, SLL16_NM, SRL16_NM)>; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 48db8ab1e77ec..12ae70493655d 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -169,13 +169,30 @@ def NMJumpTargetAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; } +class NMUImmAsmOperandClass Supers = []> : + AsmOperandClass { + let Name = "NMUImm" # Bits; + let RenderMethod = "addUImmOperands<" # Bits # ">"; + let PredicateMethod = "isConstantUImm<" # Bits # ">"; + let SuperClasses = Supers; +} + def uimm12_nm : Operand { let PrintMethod = "printUImm<12>"; let ParserMatchClass = !cast("UImm12AsmOperandClass"); } def uimm5_nm : Operand { let PrintMethod = "printUImm<5>"; - let ParserMatchClass = !cast("UImm5AsmOperandClass"); + let ParserMatchClass = NMUImmAsmOperandClass<5>; +} +def uimm4_nm : Operand { + let PrintMethod = "printUImm<4>"; + let ParserMatchClass = NMUImmAsmOperandClass<4>; +} +def uimm1_nm : Operand { + let PrintMethod = "printUImm<1>"; + let ParserMatchClass = NMUImmAsmOperandClass<1>; } def uimm3plus1_nm : Operand { let PrintMethod = "printUImm<3, 1>"; @@ -193,7 +210,7 @@ def nimm7_nm : Operand { let ParserMatchClass = !cast("Imm7AsmOperand"); let DecoderMethod = "DecodeImmM1To126"; } -def uimm4_nm : Operand { +def uimm4mask_nm : Operand { let EncoderMethod = "getUImm4MaskEncoding"; let PrintMethod = "printUImm<16>"; let ParserMatchClass = !cast("UImm4AsmOperand"); @@ -206,13 +223,6 @@ def uimm3shift_nm : Operand { let DecoderMethod = "DecodeUImm3Shift"; } -class NMUImmAsmOperandClass Supers = []> : AsmOperandClass { - let Name = "NMUImm" # Bits; - let RenderMethod = "addUImmOperands<" # Bits # ">"; - let PredicateMethod = "isConstantUImm<" # Bits # ">"; - let SuperClasses = Supers; -} - def UImm19AsmOperand : NMUImmAsmOperandClass<19>; def UImm18AsmOperand : NMUImmAsmOperandClass<18>; def UImm3AsmOperand : NMUImmAsmOperandClass<3, [UImm19AsmOperand]>; @@ -1416,6 +1426,9 @@ def DIVU_NM : DivMod<"divu", udiv>, ArithLogicR32_Enc<0b011011>; def MODU_NM : DivMod<"modu", urem>, ArithLogicR32_Enc<0b011111>; +def SOV_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), + "sov\t$rt, $rs", []>, + LogicU32_Enc<0b111110>; // 16-bit register operations let FastISelShouldIgnore = 1, isCommutable=1 in { @@ -1520,7 +1533,7 @@ class ANDI16_Enc isel> : _Pool_P16 let Inst{3...0} = imm; } -def ANDI16_NM : ArithLogicINM<"andi", uimm4_nm, GPRNM3Opnd, +def ANDI16_NM : ArithLogicINM<"andi", uimm4mask_nm, GPRNM3Opnd, imm4Mask, add>, ANDI16_Enc<0b11100>; // Arithmetic and logical instructions with 2 register operands and immediate. @@ -2309,3 +2322,36 @@ def WRPGPR_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), def RDPGPR_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), "rdpgpr\t$rt,$rs", []>, ShadowRW_Enc<0b10000>; + +def EXTW_NM : InstNM<(outs GPRNM32Opnd:$rd), + (ins GPRNM32Opnd:$rs, GPRNM32Opnd:$rt, uimm5_nm:$shift), + "extw\t$rd,$rs,$rt,$shift", []>, + _Pool_POOL32A7<0b011> { + bits<5> rd; + bits<5> rs; + bits<5> rt; + bits<5> shift; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...11} = rd; + let Inst{10...6} = shift; +} + +def ROTX_NM : InstNM<(outs GPRNM32Opnd:$rt), + (ins GPRNM32Opnd:$rs, uimm4_nm:$shiftx, + uimm5_nm:$shift, uimm1_nm:$stripe), + "rotx\t$rt,$rs,$shift,$shiftx,$stripe", []>, + _Pool_P_U12<0b1101> { + bits<5> rt; + bits<5> rs; + bits<5> shift; + bits<4> shiftx; + bits<1> stripe; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{10...7} = shiftx; + let Inst{4...0} = shift; + let Inst{6} = stripe; + let Inst{11} = 0; + let Inst{5} = 0; +} From 00f6a0bef6f7350e016440caf69b3dfb166681dd Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 6 Jan 2023 10:35:18 +0530 Subject: [PATCH 064/123] Add JALRC[16] & JALRC.HB --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 3 ++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 4026b645fe2b4..5fa69bfc06477 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -478,7 +478,8 @@ def : InstRW<[GenericWriteJump], (instrs PseudoReturnNM, TAILCALLREG_NM)>; def : InstRW<[GenericWriteJumpAndLink], (instrs BALC_NM, MOVEBALC_NM, JALRC_NM, - JALRCPseudo, BALRSC_NM)>; + JALRCHB_NM, JALRC16_NM, + JALRCPseudo, BALRSC_NM)>; // COP0 Pipeline // ============= diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 12ae70493655d..597aaca6ca32c 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1506,6 +1506,7 @@ def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM3Opnd>, ArithLogicR16_Enc<0b11>; def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>, IndirectBranch16_Enc<0>; +def JALRC16_NM : IndirectBranchNM<"jalrc", GPRNM32Opnd>, IndirectBranch16_Enc<1>; def MOVEBALC_NM : MoveBalcBase; @@ -1603,6 +1604,8 @@ let hasPostISelHook = 1, isCall = 1, isCTI = 1, Defs = [RA_NM] in { def JALRC_NM : IndirectCallNM<"jalrc", GPRNM32Opnd, GPRNM32Opnd>, IndirectCallNM_Enc<0b0000>; + def JALRCHB_NM : IndirectCallNM<"jalrc.hb", GPRNM32Opnd, GPRNM32Opnd>, + IndirectCallNM_Enc<0b0001>; def JALRCPseudo : PseudoInstNM<(outs), (ins GPRNM32Opnd:$rs), [(MipsJmpLink GPRNM32Opnd:$rs)]>, PseudoInstExpansion<(JALRC_NM RA_NM, GPRNM32Opnd:$rs)>; From 7f7ed5478ec1cab812025c96c1b14e1b0670d36d Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 6 Jan 2023 22:04:24 +0530 Subject: [PATCH 065/123] Fix operands for LWM/SWM --- .../lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 17 ++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 7f34137e2b162..13ab549abea6e 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1473,7 +1473,7 @@ class MipsOperand : public MCParsedAsmOperand { || !MipsMCRegisterClasses[ClassID].contains(getMemBase()->getGPRNM32Reg())) return false; if (isConstantMemOff()) - return isShiftedUInt(getConstantMemOff()); + return isShiftedInt(getConstantMemOff()); return getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 597aaca6ca32c..cea115e90c387 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -113,8 +113,6 @@ def UImm3ShiftAsmOperand : UImm3ShiftAsmOperandClass; def SImm12AsmOperandClass : SImmAsmOperandClass<12, []>; def NImm12AsmOperandClass : NegImmAsmOperandClass<12, []>; def NaImm12AsmOperandClass : ConstantSImmRangeAsmOperandClass<4095, 1, []>; -def UImm3Plus1AsmOperandClass : - ConstantUImmAsmOperandClass<3, [UImm5AsmOperandClass], 1>; class SImmScaledAsmOperandClass Supers = []> : AsmOperandClass{ @@ -146,8 +144,6 @@ class NMMemUimmAsmOperand"; - let DiagnosticType = !if(!eq(Shift, 0), "MemUImm" # Width, - "MemUImm" # Width # "Lsl" # Shift); } class NMMemSimmAsmOperand"; - let DiagnosticType = !if(!eq(Shift, 0), "MemUImm" # Width, - "MemUImm" # Width # "Lsl" # Shift); } def NMJumpTargetAsmOperand : AsmOperandClass { @@ -170,11 +164,12 @@ def NMJumpTargetAsmOperand : AsmOperandClass { } class NMUImmAsmOperandClass Supers = []> : + list Supers = [], + int Offset = 0> : AsmOperandClass { - let Name = "NMUImm" # Bits; - let RenderMethod = "addUImmOperands<" # Bits # ">"; - let PredicateMethod = "isConstantUImm<" # Bits # ">"; + let Name = "NMUImm" # Bits # "_" # Offset; + let RenderMethod = "addConstantUImmOperands<" # Bits # "," # Offset # ">"; + let PredicateMethod = "isConstantUImm<" # Bits # "," # Offset # ">"; let SuperClasses = Supers; } @@ -196,7 +191,7 @@ def uimm1_nm : Operand { } def uimm3plus1_nm : Operand { let PrintMethod = "printUImm<3, 1>"; - let ParserMatchClass = !cast("UImm3Plus1AsmOperandClass"); + let ParserMatchClass = NMUImmAsmOperandClass<3, [], 1>; } def nimm12_nm : Operand { let PrintMethod = "printUImm<12>"; From 71bff7a58c8fe321ec243e07f86fac598687a44e Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 7 Jan 2023 11:36:42 +0530 Subject: [PATCH 066/123] Fix encodings for UALWM, UASWM and rewrite UALW/UASW as aliases --- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 4 ++-- llvm/lib/Target/Mips/MipsSERegisterInfo.cpp | 4 ++-- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 4 ++-- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 16 ++++++++-------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index bcec89dcc02eb..d64de7ab93057 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1208,11 +1208,11 @@ unsigned MipsMCCodeEmitter:: getMemEncodingNMImm9(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { - // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. + // Base register is encoded in bits 13-9, offset is encoded in bits 8-0. assert(MI.getOperand(OpNo).isReg()); unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 9; - unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + int OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); return (OffBits & 0x1FF) | RegBits; } diff --git a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp index 222315753f03f..b09b3ddd01e89 100644 --- a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -115,8 +115,8 @@ static inline unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode, case Mips::SWs9_NM: case Mips::SHs9_NM: case Mips::SBs9_NM: - case Mips::UALW_NM: - case Mips::UASW_NM: + case Mips::UALWM_NM: + case Mips::UASWM_NM: case Mips::UALH_NM: case Mips::UASH_NM: return 9; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 5fa69bfc06477..0932ae511f958 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -729,7 +729,7 @@ def : InstRW<[GenericWriteLoad], (instrs LW_NM, LWGP_NM, LWs9_NM, LWX_NM, LWXS_NM, LHUX_NM, LHUXS_NM, LHX_NM, LHXS_NM, LBUX_NM, LBX_NM, RESTOREJRC_NM, RESTORE_NM, SAVE_NM, - UALH_NM, UALW_NM, LWM_NM, UALWM_NM, + UALH_NM, LWM_NM, UALWM_NM, LWPC_NM, LW16_NM, LH16_NM, LHU16_NM, LB16_NM, LBU16_NM, LBGP_NM, LBUGP_NM, LHGP_NM, LHUGP_NM, LW4x4_NM)>; @@ -739,7 +739,7 @@ def: InstRW<[GenericWriteStore], (instrs SW_NM, SWs9_NM, SW16_NM, SH16_NM, SB_NM, SBs9_NM, SB16_NM, LWGP16_NM, SWGP16_NM, LWSP16_NM, SWSP16_NM, SW4x4_NM, SWX_NM, SWXS_NM, SHX_NM, SHXS_NM, SBX_NM, - UASH_NM, UASW_NM, SWM_NM, UASWM_NM, SWPC_NM)>; + UASH_NM, SWM_NM, UASWM_NM, SWPC_NM)>; // microMIPS32r6 // ============= diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index cea115e90c387..6c4e1d4ab037d 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -190,7 +190,6 @@ def uimm1_nm : Operand { let ParserMatchClass = NMUImmAsmOperandClass<1>; } def uimm3plus1_nm : Operand { - let PrintMethod = "printUImm<3, 1>"; let ParserMatchClass = NMUImmAsmOperandClass<3, [], 1>; } def nimm12_nm : Operand { @@ -1271,15 +1270,14 @@ def RESTORE_NM : SaveRestore<"restore">, InstSize32; def RESTOREJRC_NM : SaveRestore<"restore.jrc">, InstSize32; class LoadMultipleNM : - InstNM<(outs GPRNM32Opnd:$rt), (ins mem_nms9:$addr, uimm3plus1_nm:$count), + InstNM<(outs GPRNM32Opnd:$rt), + (ins mem_nms9:$addr, uimm3plus1_nm:$count), !strconcat(opstr, "\t$rt, $addr, $count"), []> { - let DecoderMethod = "DecodeMem"; let mayLoad = 1; } class StoreMultipleNM : InstNM<(outs), (ins GPRNM32Opnd:$rt, mem_nms9:$addr, uimm3plus1_nm:$count), !strconcat(opstr, "\t$rt, $addr, $count"), []> { - let DecoderMethod = "DecodeMem"; let mayStore = 1; } @@ -2044,8 +2042,10 @@ def UALWM_NM : LoadMultipleNM<"ualwm">, LSMem_S9_Mult_Enc<0b0101>; def SWM_NM : StoreMultipleNM<"swm">, LSMem_S9_Mult_Enc<0b1100>; def UASWM_NM : StoreMultipleNM<"uaswm">, LSMem_S9_Mult_Enc<0b1101>; -def UALW_NM : UnalignedLoad<"ualw", NMUnalignedLW>, LSMem_S9_Enc<0b101, 0b0000>; -def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b1000>; +def UALW_NM : MipsInstAlias<"ualw $rt, $addr", + (UALWM_NM GPRNM32Opnd:$rt, mem_nms9:$addr, 1)>; +def UASW_NM : MipsInstAlias<"uasw $rt, $addr", + (UASWM_NM GPRNM32Opnd:$rt, mem_nms9:$addr, 1)>; //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; @@ -2134,9 +2134,9 @@ def : NMPat<(i32 (extloadi16 addrindexed:$addr)), (LHUX_NM addrindexed:$addr, 0) // Catching out-of-range immediate unaligned loads/stores. def : NMPat<(i32 (NMUnalignedLW GPRNM32:$rs, GPRNM32:$src)), - (UALW_NM GPRNM32:$rs, 0, GPRNM32:$src)>; + (UALWM_NM GPRNM32:$rs, GPRNM32:$src, 1)>; def : NMPat<(NMUnalignedSW GPRNM32:$rt, GPRNM32:$rs), - (UASW_NM GPRNM32:$rt, GPRNM32:$rs, 0)>; + (UASWM_NM GPRNM32:$rt, GPRNM32:$rs, 0, 1)>; def : NMPat<(i32 (NMUnalignedLH GPRNM32:$rs, GPRNM32:$src)), (UALH_NM GPRNM32:$rs, 0, GPRNM32:$src)>; def : NMPat<(NMUnalignedSH GPRNM32:$rt, GPRNM32:$rs), From 0f807c41d135eb18600ef10344f56f92e43c34eb Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 14 Jan 2023 17:50:25 +0530 Subject: [PATCH 067/123] Add encodings for 16/32 bit SAVE/RESTORE variants --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 111 ++++++++++++++++++ .../Mips/Disassembler/MipsDisassembler.cpp | 50 ++++++++ .../Mips/MCTargetDesc/MipsInstPrinter.cpp | 15 +++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 37 ++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 8 ++ .../Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 15 ++- llvm/lib/Target/Mips/MipsInstrInfo.cpp | 4 +- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 5 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 86 ++++++++++++-- .../Mips/NanoMipsLoadStoreOptimizer.cpp | 6 +- 10 files changed, 322 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 13ab549abea6e..48a08f223af0f 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -208,6 +208,7 @@ class MipsAsmParser : public MCTargetAsmParser { OperandMatchResultTy parseJumpTarget(OperandVector &Operands); OperandMatchResultTy parseInvNum(OperandVector &Operands); OperandMatchResultTy parseRegisterList(OperandVector &Operands); + OperandMatchResultTy parseNMRegisterList(OperandVector &Operands); bool searchSymbolAlias(OperandVector &Operands); @@ -946,6 +947,15 @@ class MipsOperand : public MCParsedAsmOperand { return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); } + // Find the next (or previous) i'th register in sequence for NanoMips + unsigned getGPRNM32RegNext(int i = 1) const { + assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && + ((signed)RegIdx.Index + i >= 0) && (RegIdx.Index + i <= 31) && + "Invalid access!"); + unsigned ClassID = Mips::GPRNM32RegClassID; + return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index + i); + } + unsigned getGPRNM4ZeroReg() const { assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); unsigned ClassID = Mips::GPRNM32RegClassID; @@ -1660,6 +1670,31 @@ class MipsOperand : public MCParsedAsmOperand { bool isRegList() const { return Kind == k_RegList; } + bool isNMRegList16() const { + if (!isRegList()) + return false; + + // List must not be empty + unsigned Size = RegList.List->size(); + if (Size == 0) + return false; + + // List must start with $fp or $ra + unsigned R0 = RegList.List->front(); + unsigned R1 = RegList.List->back(); + if (!(R0 == Mips::FP_NM || R0 == Mips::RA_NM)) + return false; + + // If $gp is specified, it must be part of a + // contiguous sequence of registers + if (R0 == Mips::FP_NM && R1 == Mips::GP_NM) + return (Size == 15); + if (R0 == Mips::RA_NM && R1 == Mips::GP_NM) + return (Size == 14); + + return true; + } + StringRef getToken() const { assert(Kind == k_Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); @@ -7258,6 +7293,82 @@ MipsAsmParser::parseRegisterList(OperandVector &Operands) { return MatchOperand_Success; } +OperandMatchResultTy +MipsAsmParser::parseNMRegisterList(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + SmallVector Regs; + unsigned RegNo; + unsigned PrevReg = Mips::NoRegister; + bool RegRange = false; + SmallVector, 16> TmpOperands; + MipsOperand *RegFirst; + + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_ParseFail; + + SMLoc S = Parser.getTok().getLoc(); + + while (parseAnyRegister(TmpOperands) == MatchOperand_Success) { + SMLoc E = getLexer().getLoc(); + MipsOperand &Reg = static_cast(*TmpOperands.back()); + RegNo = Reg.getGPRNM32Reg(); + + if (RegRange) { + unsigned i = 1; + PrevReg = RegFirst->getGPRNM32RegNext(i++); + while (PrevReg != RegNo) { + if (PrevReg == Mips::RA_NM) { + Error(E, "invalid register range"); + return MatchOperand_ParseFail; + } + Regs.push_back(PrevReg); + PrevReg = RegFirst->getGPRNM32RegNext(i++); + } + RegRange = false; + } + else if (PrevReg == Mips::RA_NM && RegNo != Mips::S0_NM) { + Error(E, "register sequence must continue at $s0 after $ra"); + return MatchOperand_ParseFail; + } + else if (Regs.size() == Regs.capacity()) { + Error(E, "too many registers in list"); + return MatchOperand_ParseFail; + } else if ((PrevReg != Mips::RA_NM) && + (PrevReg != Mips::NoRegister) && + (Reg.getGPRNM32RegNext(-1) != PrevReg) && + (RegNo != Mips::GP_NM)) { + Error(E, "consecutive register numbers expected"); + return MatchOperand_ParseFail; + } + + Regs.push_back(RegNo); + + if (Parser.getTok().is(AsmToken::Minus)) { + RegRange = true; + RegFirst = &Reg; + } + + if (Parser.getTok().is(AsmToken::EndOfStatement)) + break; + + if (Parser.getTok().isNot(AsmToken::Minus) && + Parser.getTok().isNot(AsmToken::Comma)) { + Error(E, "',' or '-' expected"); + return MatchOperand_ParseFail; + } + + Lex(); // Consume comma or minus + if (Parser.getTok().isNot(AsmToken::Dollar)) + break; + + PrevReg = RegNo; + } + + SMLoc E = Parser.getTok().getLoc(); + Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); + return MatchOperand_Success; +} + /// Sometimes (i.e. load/stores) the operand may be followed immediately by /// either this. /// ::= '(', register, ')' diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 8b72182a2b107..ab962df3b771b 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -626,6 +626,16 @@ static DecodeStatus DecodeUImm3Shift(MCInst &Inst, unsigned Value, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeNMRegListOperand(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeNMRegList16Operand(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static MCDisassembler *createMipsDisassembler( const Target &T, const MCSubtargetInfo &STI, @@ -3002,3 +3012,43 @@ static DecodeStatus DecodeUImm3Shift(MCInst &Inst, unsigned Value, Inst.addOperand(MCOperand::createImm(Value)); return MCDisassembler::Success; } + +static DecodeStatus DecodeNMRegListOperand(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned RegStart = fieldFromInstruction(Insn, 5, 5); + unsigned RegCount = fieldFromInstruction(Insn, 1, 4); + unsigned GP_bit = fieldFromInstruction(Insn, 0, 1); + unsigned i; + unsigned RegNo; + + Inst.addOperand(MCOperand::createReg(getReg(Decoder, + Mips::GPRNM32RegClassID, + RegStart))); + for (i = RegStart + 1; i < RegStart + RegCount; i++) { + if (i == RegStart + RegCount - 1 && GP_bit) + RegNo = 28; + else if (i > 31) + RegNo = 16 + (i % 32); // $ra+1 wraps to $s0 + else + RegNo = i; + Inst.addOperand(MCOperand::createReg(getReg(Decoder, + Mips::GPRNM32RegClassID, + RegNo))); + } + return MCDisassembler::Success; +} + +static DecodeStatus DecodeNMRegList16Operand(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned RegStart = 30 + fieldFromInstruction(Insn, 4, 1); + unsigned RegCount = fieldFromInstruction(Insn, 0, 4); + // Re-encode the parameters for 32-bit instruction operand + // and call it's decoder + return DecodeNMRegListOperand(Inst, + (RegStart << 5) | (RegCount << 1), + Address, Decoder); +} diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp index eb49aa483343c..33fc90ea6ba5f 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp @@ -106,6 +106,21 @@ void MipsInstPrinter::printInst(const MCInst *MI, uint64_t Address, printSaveRestore(MI, O); O << "\n"; return; + case Mips::RESTORE_NM: + O << "\trestore\t"; + printSaveRestore(MI, O); + return; + case Mips::SAVE16_NM: + case Mips::SAVE_NM: + O << "\tsave\t"; + printSaveRestore(MI, O); + return; + case Mips::RESTOREJRC16_NM: + case Mips::RESTOREJRC_NM: + O << "\trestore.jrc\t"; + printSaveRestore(MI, O); + O << "\n"; + return; } // Try to print any aliases first. diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index d64de7ab93057..6ee165b5da4ec 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1561,4 +1561,41 @@ MipsMCCodeEmitter::getUImm3ShiftEncoding(const MCInst &MI, unsigned OpNo, llvm_unreachable("Unexpected value"); } +unsigned +MipsMCCodeEmitter::getNMRegListEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + unsigned res = 0; + unsigned gp = 0; + // Register list operand is always first operand of instruction and it is + // placed before memory operand (register + imm). + for (unsigned I = OpNo; I < MI.getNumOperands(); I++) { + unsigned Reg = MI.getOperand(I).getReg(); + unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); + if (res == 0) + res |= (RegNo << 4); + if (RegNo == 28) + gp = 1; + res++; + } + return (res << 1 | gp); +} + +unsigned +MipsMCCodeEmitter::getNMRegList16Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + unsigned res = 0x10; + // Register list operand is always first operand of instruction and it is + // placed before memory operand (register + imm). + for (unsigned I = OpNo; I < MI.getNumOperands(); I++) { + unsigned Reg = MI.getOperand(I).getReg(); + unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); + if (RegNo == 30) + res &= 0xf; + res++; + } + return res; +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index a4c94407101c5..bbec68aa329dd 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -351,6 +351,14 @@ class MipsMCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getNMRegListEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getNMRegList16Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + private: void LowerCompactBranch(MCInst& Inst) const; }; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index dea78d9732ee0..e90998a40cd5d 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -144,7 +144,20 @@ class MipsMCInstrAnalysis : public MCInstrAnalysis { unsigned NumOps = Inst.getNumOperands(); if (NumOps == 0) return false; - switch (Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType) { + + // FIXME: Can't figure out why OperandType is UNKNOWN for + // NanoMips register lists so work-around it for now + unsigned Opcode = Inst.getOpcode(); + switch (Opcode) { + case Mips::SAVE_NM: + case Mips::RESTORE_NM: + case Mips::RESTOREJRC_NM: + case Mips::SAVE16_NM: + case Mips::RESTOREJRC16_NM: + return false; + } + + switch (Info->get(Opcode).OpInfo[NumOps - 1].OperandType) { case MCOI::OPERAND_UNKNOWN: case MCOI::OPERAND_IMMEDIATE: { // j, jal, jalx, jals diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index 8b2a44ee6e522..b5668449c753d 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -1198,7 +1198,7 @@ void llvm::MipsInstrInfo::buildOutlinedFrame( Et = std::prev(MBB.end()); } - MachineInstr *SaveRAtoStack = BuildMI(MF, DebugLoc(), get(Mips::SAVE_NM)) + MachineInstr *SaveRAtoStack = BuildMI(MF, DebugLoc(), get(Mips::SAVE16_NM)) .addImm(16) .addReg(Mips::RA_NM); @@ -1306,7 +1306,7 @@ MachineBasicBlock::iterator MipsInstrInfo::insertOutlinedCall( // Default case. Save and Restore from stack pointer : else { - SaveRA = BuildMI(MF, DebugLoc(), get(Mips::SAVE_NM)) + SaveRA = BuildMI(MF, DebugLoc(), get(Mips::SAVE16_NM)) .addImm(16) .addReg(Mips::RA_NM); diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 0932ae511f958..cc12f52645408 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -728,8 +728,9 @@ def : InstRW<[GenericWriteLoad], (instrs LW_NM, LWGP_NM, LWs9_NM, LBU_NM, LBUs9_NM, LB_NM, LBs9_NM, LWX_NM, LWXS_NM, LHUX_NM, LHUXS_NM, LHX_NM, LHXS_NM, LBUX_NM, LBX_NM, - RESTOREJRC_NM, RESTORE_NM, SAVE_NM, - UALH_NM, LWM_NM, UALWM_NM, + RESTOREJRC16_NM, RESTOREJRC_NM, + RESTORE_NM, SAVE_NM, SAVE16_NM, + UALH_NM, LWM_NM, UALWM_NM, LWPC_NM, LW16_NM, LH16_NM, LHU16_NM, LB16_NM, LBU16_NM, LBGP_NM, LBUGP_NM, LHGP_NM, LHUGP_NM, LW4x4_NM)>; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 6c4e1d4ab037d..c30aa1b83bc92 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -173,10 +173,29 @@ class NMUImmAsmOperandClass Supers = []> : + AsmOperandClass { + let Name = "NMUImm" # Bits # "_s" # Shift; + let RenderMethod = "addConstantUImmOperands<32>"; + let PredicateMethod = "isScaledUImm<" # Bits # "," # Shift # ">"; + let SuperClasses = Supers; +} + def uimm12_nm : Operand { let PrintMethod = "printUImm<12>"; let ParserMatchClass = !cast("UImm12AsmOperandClass"); } + +def uimm12s3_nm : Operand { + let PrintMethod = "printUImm<12>"; + let ParserMatchClass = NMUImmScaledAsmOperandClass<9, 3, []>; +} +def uimm8s4_nm : Operand { + let PrintMethod = "printUImm<8>"; + let ParserMatchClass = NMUImmScaledAsmOperandClass<4, 4, [uimm12s3_nm.ParserMatchClass]>; +} def uimm5_nm : Operand { let PrintMethod = "printUImm<5>"; let ParserMatchClass = NMUImmAsmOperandClass<5>; @@ -1252,22 +1271,75 @@ class AdjustStack : let hasNoSchedulingInfo = 1; } -def nmreglist : Operand { +class NMRegListAsmOperandClass Supers = []> + : AsmOperandClass { + let Name = "NMRegList32"; + let RenderMethod = "addRegListOperands"; + let PredicateMethod = "isRegList"; + let SuperClasses = Supers; + let ParserMethod = "parseNMRegisterList"; +} + +class NMRegList16AsmOperandClass Supers = []> + : AsmOperandClass { + let Name = "NMRegList16"; + let PredicateMethod = "isNMRegList16"; + let RenderMethod = "addRegListOperands"; + let SuperClasses = Supers; + let ParserMethod = "parseNMRegisterList"; +} + +def nmreglist16 : Operand { + let PrintMethod = "printNanoMipsRegisterList"; + let ParserMatchClass = NMRegList16AsmOperandClass<>; + let DecoderMethod = "DecodeNMRegList16Operand"; + let EncoderMethod = "getNMRegList16Encoding"; +} + +def nmreglist : Operand { let PrintMethod = "printNanoMipsRegisterList"; + let ParserMatchClass = NMRegListAsmOperandClass<>; + let DecoderMethod = "DecodeNMRegListOperand"; + let EncoderMethod = "getNMRegListEncoding"; } -class SaveRestore : +class SaveRestore : InstNM<(outs), - (ins uimm12_nm:$adj, nmreglist:$regs, variable_ops), + (ins Od:$adj, RL:$regs, variable_ops), !strconcat(opstr, "\t$adj$regs"), []> { let Defs = [SP_NM]; let Uses = [SP_NM]; let hasSideEffects = 1; - let isCodeGenOnly = 1; } -def SAVE_NM : SaveRestore<"save">, InstSize32; -def RESTORE_NM : SaveRestore<"restore">, InstSize32; -def RESTOREJRC_NM : SaveRestore<"restore.jrc">, InstSize32; + +class _Pool_PP_SR isel> : _Pool_P_U12<0b0011> { + let Inst{20} = 0; + let Inst{1...0} = isel; +} + +class SaveRestore32_Enc isel> : _Pool_PP_SR { + bits<12> adj; + bits<10> regs; + let Inst{11...3} = adj{11...3}; + let Inst{25...21} = regs{9...5}; + let Inst{19...16} = regs{4...1}; + let Inst{2} = regs{0}; +} + +def SAVE_NM : SaveRestore<"save", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b00>; +def RESTORE_NM : SaveRestore<"restore", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b10>; +def RESTOREJRC_NM : SaveRestore<"restore.jrc", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b11>; + +class SaveRestore16_Enc isel> : _Pool_P16_SR { + bits<8> adj; + bits<5> regs; + let Inst{7...4} = adj{7...4}; + let Inst{9} = regs{4}; + let Inst{3...0} = regs{3...0}; +} + +def SAVE16_NM : SaveRestore<"save", uimm8s4_nm, nmreglist16>, SaveRestore16_Enc<0b0>; +def RESTOREJRC16_NM : SaveRestore<"restore.jrc", uimm8s4_nm, nmreglist16>, SaveRestore16_Enc<0b1>; class LoadMultipleNM : InstNM<(outs GPRNM32Opnd:$rt), diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index bf9f37223d493..0ed80da047fed 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -332,9 +332,9 @@ bool NMLoadStoreOpt::generateSaveOrRestore(MachineBasicBlock &MBB, // because it needs to be the last instruction in the basic block. If // possible, it will be generated with NewStackOffset. unsigned Opcode = IsRestore - ? ((Return && !NewStackOffset) ? Mips::RESTOREJRC_NM + ? ((Return && !NewStackOffset) ? Mips::RESTOREJRC16_NM : Mips::RESTORE_NM) - : Mips::SAVE_NM; + : Mips::SAVE16_NM; auto InsertBefore = std::next(MBBIter((Return && !NewStackOffset) ? Return : AdjustStack)); auto DL = Return ? Return->getDebugLoc() : AdjustStack->getDebugLoc(); @@ -371,7 +371,7 @@ bool NMLoadStoreOpt::generateSaveOrRestore(MachineBasicBlock &MBB, // In case return is also consumed, we should put restore.jrc after // return, to make sure it is very last instruction. InsertBefore = std::next(MBBIter(Return)); - BuildMI(MBB, InsertBefore, DL, TII->get(Mips::RESTOREJRC_NM)) + BuildMI(MBB, InsertBefore, DL, TII->get(Mips::RESTOREJRC16_NM)) .addImm(NewStackOffset); MBB.erase(Return); } else { From acbe858c9ffbc9bb163ba091a58b7ec17da21b66 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 17 Jan 2023 20:08:09 +0530 Subject: [PATCH 068/123] Handle SAVE/RESTORE variants with empty register lists --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 50 +++++++++++++++++-- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 40 +++++++-------- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 11 ++++ 3 files changed, 76 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 48a08f223af0f..cbacc9ae993a1 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1677,7 +1677,7 @@ class MipsOperand : public MCParsedAsmOperand { // List must not be empty unsigned Size = RegList.List->size(); if (Size == 0) - return false; + return true; // List must start with $fp or $ra unsigned R0 = RegList.List->front(); @@ -1835,6 +1835,16 @@ class MipsOperand : public MCParsedAsmOperand { return Op; } + static std::unique_ptr + CreateRegListNM(SmallVectorImpl &Regs, SMLoc StartLoc, SMLoc EndLoc, + MipsAsmParser &Parser) { + auto Op = std::make_unique(k_RegList, Parser); + Op->RegList.List = new SmallVector(Regs.begin(), Regs.end()); + Op->StartLoc = StartLoc; + Op->EndLoc = EndLoc; + return Op; + } + bool isGPRZeroAsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0; } @@ -7303,9 +7313,6 @@ MipsAsmParser::parseNMRegisterList(OperandVector &Operands) { SmallVector, 16> TmpOperands; MipsOperand *RegFirst; - if (Parser.getTok().isNot(AsmToken::Dollar)) - return MatchOperand_ParseFail; - SMLoc S = Parser.getTok().getLoc(); while (parseAnyRegister(TmpOperands) == MatchOperand_Success) { @@ -7364,8 +7371,41 @@ MipsAsmParser::parseNMRegisterList(OperandVector &Operands) { PrevReg = RegNo; } + /* Parse an alternate format with count and start-reg instead + of register list */ + if (Regs.size() == 0) { + if (getLexer().getTok().is(AsmToken::Integer)) { + unsigned Count = Parser.getTok().getIntVal(); + Lex(); + SMLoc E = Parser.getTok().getLoc(); + if (Count > 16) { + Error(E, "too many registers in list"); + return MatchOperand_ParseFail; + } + if (Count > 0) { + if (Parser.getTok().isNot(AsmToken::Minus) && + Parser.getTok().isNot(AsmToken::Comma)) { + Error(E, "',' or '-' expected"); + return MatchOperand_ParseFail; + } + Lex(); // Consume comma or minus + E = Parser.getTok().getLoc(); + if (parseAnyRegister(TmpOperands) == MatchOperand_Success) { + MipsOperand &Reg = static_cast(*TmpOperands.back()); + unsigned i = 1; + while (i < Count) + Regs.push_back(Reg.getGPRNM32RegNext(i++)); + } + else + return MatchOperand_ParseFail; + } + } + else + return MatchOperand_ParseFail; + } + SMLoc E = Parser.getTok().getLoc(); - Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); + Operands.push_back(MipsOperand::CreateRegListNM(Regs, S, E, *this)); return MatchOperand_Success; } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 6ee165b5da4ec..46dd82aec5e89 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1567,17 +1567,16 @@ MipsMCCodeEmitter::getNMRegListEncoding(const MCInst &MI, unsigned OpNo, const MCSubtargetInfo &STI) const { unsigned res = 0; unsigned gp = 0; - // Register list operand is always first operand of instruction and it is - // placed before memory operand (register + imm). - for (unsigned I = OpNo; I < MI.getNumOperands(); I++) { - unsigned Reg = MI.getOperand(I).getReg(); - unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); - if (res == 0) - res |= (RegNo << 4); - if (RegNo == 28) - gp = 1; - res++; - } + if (!MI.getOperand(OpNo).isImm() || MI.getOperand(OpNo).getImm() != 0) + for (unsigned I = OpNo; I < MI.getNumOperands(); I++) { + unsigned Reg = MI.getOperand(I).getReg(); + unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); + if (res == 0) + res |= (RegNo << 4); + if (RegNo == 28) + gp = 1; + res++; + } return (res << 1 | gp); } @@ -1585,15 +1584,16 @@ unsigned MipsMCCodeEmitter::getNMRegList16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { - unsigned res = 0x10; - // Register list operand is always first operand of instruction and it is - // placed before memory operand (register + imm). - for (unsigned I = OpNo; I < MI.getNumOperands(); I++) { - unsigned Reg = MI.getOperand(I).getReg(); - unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); - if (RegNo == 30) - res &= 0xf; - res++; + unsigned res = 0; + if (!MI.getOperand(OpNo).isImm() || MI.getOperand(OpNo).getImm() != 0) { + res = 0x10; + for (unsigned I = OpNo; I < MI.getNumOperands(); I++) { + unsigned Reg = MI.getOperand(I).getReg(); + unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); + if (RegNo == 30) + res &= 0xf; + res++; + } } return res; } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index c30aa1b83bc92..299de91a9940a 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1330,6 +1330,13 @@ def SAVE_NM : SaveRestore<"save", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b0 def RESTORE_NM : SaveRestore<"restore", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b10>; def RESTOREJRC_NM : SaveRestore<"restore.jrc", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b11>; +def SAVE_NOREG_NM : MipsInstAlias<"save $adj", + (SAVE_NM uimm12s3_nm:$adj, 0)>; +def RESTORE_NOREG_NM : MipsInstAlias<"restore $adj", + (RESTORE_NM uimm12s3_nm:$adj, 0)>; +def RESTOREJRC_NOREG_NM : MipsInstAlias<"restore.jrc $adj", + (RESTOREJRC_NM uimm12s3_nm:$adj, 0)>; + class SaveRestore16_Enc isel> : _Pool_P16_SR { bits<8> adj; bits<5> regs; @@ -1340,6 +1347,10 @@ class SaveRestore16_Enc isel> : _Pool_P16_SR { def SAVE16_NM : SaveRestore<"save", uimm8s4_nm, nmreglist16>, SaveRestore16_Enc<0b0>; def RESTOREJRC16_NM : SaveRestore<"restore.jrc", uimm8s4_nm, nmreglist16>, SaveRestore16_Enc<0b1>; +def SAVE16_NOREG_NM : MipsInstAlias<"save $adj", + (SAVE16_NM uimm8s4_nm:$adj, 0)>; +def RESTOREJRC16_NOREG_NM : MipsInstAlias<"restore.jrc $adj", + (RESTOREJRC16_NM uimm8s4_nm:$adj, 0)>; class LoadMultipleNM : InstNM<(outs GPRNM32Opnd:$rt), From 138c0b3c8967a72e20af13252d51e510d5be34bf Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 15 Jan 2023 05:54:52 +0530 Subject: [PATCH 069/123] Change NOT_NM to NOT16_NM and add 32-bit NOT encoding --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index cc12f52645408..d0c653b45fb80 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -126,7 +126,7 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, LSA_NM, MOVEP_NM, MOVE16_NM, MOD_NM, MODU_NM, MOVEPREV_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, - NOT_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, + NOT16_NM, NOR_NM, OR_NM, OR16_NM, ORI_NM, ROTRV_NM, ROTR_NM, ROTX_NM, SEB_NM, SEH_NM, SEQI_NM, SLL_NM, SLLV_NM, SLT_NM, SLTI_NM, SLTIU_NM, SLTU_NM, SOV_NM, SRAV_NM, SRA_NM, SRLV_NM, SRL_NM, SUB_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 299de91a9940a..2c59cf63fe055 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1572,8 +1572,10 @@ def BYTEREVW_NM : ReverseNM<"byterevw", GPRNM32Opnd, bswap>; def TEQ_NM : Trap_Desc<"teq", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b0>; def TNE_NM : Trap_Desc<"tne", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b1>; -def NOT_NM : ArithLogicR16U_Desc<"not", GPRNM3Opnd, not>, +def NOT16_NM : ArithLogicR16U_Desc<"not", GPRNM3Opnd, not>, ArithLogicR16_Enc<0b00>; +def NOT_NM : MipsInstAlias<"not $rt, $rs", + (NOR_NM GPRNM32Opnd:$rt, GPRNM32Opnd:$rs, ZERO_NM)>; def XOR16_NM : ArithLogicR16_Desc<"xor", GPRNM3Opnd>, ArithLogicR16_Enc<0b01>; def AND16_NM : ArithLogicR16_Desc<"and", GPRNM3Opnd>, From e11b64551cfce145fb323243c70f6d3fe859f006 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 15 Jan 2023 05:55:48 +0530 Subject: [PATCH 070/123] Check pos+size<=32 for EXT/INS --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index cbacc9ae993a1..2d4eaecbb2191 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -6206,7 +6206,9 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) return Match_RequiresDifferentOperands; return Match_Success; - case Mips::DINS: { + case Mips::DINS: + case Mips::EXT_NM: + case Mips::INS_NM: { assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && "Operands must be immediates for dins!"); const signed Pos = Inst.getOperand(2).getImm(); From aa706ff7a5049b139e4d4dea50cad6e8388d3a8d Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 15 Jan 2023 05:57:53 +0530 Subject: [PATCH 071/123] Fix incorrect SOV encoding --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 2c59cf63fe055..54bfd3e1fce9f 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1502,9 +1502,8 @@ def DIVU_NM : DivMod<"divu", udiv>, ArithLogicR32_Enc<0b011011>; def MODU_NM : DivMod<"modu", urem>, ArithLogicR32_Enc<0b011111>; -def SOV_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), - "sov\t$rt, $rs", []>, - LogicU32_Enc<0b111110>; +def SOV_NM : ArithLogicR32_Desc<"sov", GPRNM32Opnd>, + ArithLogicR32_Enc<0b111110>; // 16-bit register operations let FastISelShouldIgnore = 1, isCommutable=1 in { From 6a33017583631dd67d260d9def32bd4f194f2521 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 15 Jan 2023 05:59:24 +0530 Subject: [PATCH 072/123] Remove source-destination matching constraint This seems to enforce and override the value of source from destination instead of just introducing a check. --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 54bfd3e1fce9f..7a7f0f7be5668 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -708,7 +708,6 @@ class Arith4x4_Desc { Format Form = FrmR; - let Constraints = "$rt = $dst"; } class Arith4x4_Enc isel>: _Pool_P16_4X4 { @@ -744,9 +743,7 @@ class ArithLogicR16_Desc: InstNM<(outs RO:$dst), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$dst, $rs, $rt"), - [(set RO:$dst, (OpNode RO:$rs, RO:$rt))]> { - let Constraints = "$dst = $rt"; -} + [(set RO:$dst, (OpNode RO:$rs, RO:$rt))]>; class ArithLogicR16U_Desc: From 36ebd6f440c3543f9e6f7aa4e7c5962fc219d667 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 17 Jan 2023 20:20:59 +0530 Subject: [PATCH 073/123] Add missing space after comma in instruction assembly --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 7a7f0f7be5668..6dd8af73be5c1 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -2397,14 +2397,14 @@ class ShadowRW_Enc isel>: _Pool_POOL32Axf_5_group3 { } def WRPGPR_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), - "wrpgpr\t$rt,$rs", []>, ShadowRW_Enc<0b11000>; + "wrpgpr\t$rt, $rs", []>, ShadowRW_Enc<0b11000>; def RDPGPR_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs), - "rdpgpr\t$rt,$rs", []>, ShadowRW_Enc<0b10000>; + "rdpgpr\t$rt, $rs", []>, ShadowRW_Enc<0b10000>; def EXTW_NM : InstNM<(outs GPRNM32Opnd:$rd), (ins GPRNM32Opnd:$rs, GPRNM32Opnd:$rt, uimm5_nm:$shift), - "extw\t$rd,$rs,$rt,$shift", []>, + "extw\t$rd, $rs, $rt, $shift", []>, _Pool_POOL32A7<0b011> { bits<5> rd; bits<5> rs; @@ -2419,7 +2419,7 @@ def EXTW_NM : InstNM<(outs GPRNM32Opnd:$rd), def ROTX_NM : InstNM<(outs GPRNM32Opnd:$rt), (ins GPRNM32Opnd:$rs, uimm4_nm:$shiftx, uimm5_nm:$shift, uimm1_nm:$stripe), - "rotx\t$rt,$rs,$shift,$shiftx,$stripe", []>, + "rotx\t$rt, $rs, $shift, $shiftx, $stripe", []>, _Pool_P_U12<0b1101> { bits<5> rt; bits<5> rs; From affad6221efcdd350e112ecdb647354e071c662f Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 17 Jan 2023 20:23:15 +0530 Subject: [PATCH 074/123] Fix shiftx operand format for ROTX --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 6dd8af73be5c1..fbfd884cee7e1 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -219,6 +219,10 @@ def uimm16_nm : Operand { let PrintMethod = "printUImm<16>"; let ParserMatchClass = !cast("SImm16AsmOperandClass"); } +def uimm5s1_nm : Operand { + let PrintMethod = "printUImm<5>"; + let ParserMatchClass = NMUImmScaledAsmOperandClass<4, 1>; +} def nimm7_nm : Operand { let ParserMatchClass = !cast("Imm7AsmOperand"); let DecoderMethod = "DecodeImmM1To126"; @@ -2417,18 +2421,18 @@ def EXTW_NM : InstNM<(outs GPRNM32Opnd:$rd), } def ROTX_NM : InstNM<(outs GPRNM32Opnd:$rt), - (ins GPRNM32Opnd:$rs, uimm4_nm:$shiftx, + (ins GPRNM32Opnd:$rs, uimm5s1_nm:$shiftx, uimm5_nm:$shift, uimm1_nm:$stripe), "rotx\t$rt, $rs, $shift, $shiftx, $stripe", []>, _Pool_P_U12<0b1101> { bits<5> rt; bits<5> rs; bits<5> shift; - bits<4> shiftx; + bits<5> shiftx; bits<1> stripe; let Inst{25...21} = rt; let Inst{20...16} = rs; - let Inst{10...7} = shiftx; + let Inst{10...7} = shiftx{4...1}; let Inst{4...0} = shift; let Inst{6} = stripe; let Inst{11} = 0; From 4bfd3914907aeecd86e1ec0752e4103c79204848 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 17 Jan 2023 20:33:58 +0530 Subject: [PATCH 075/123] Re-factor P16.MV pool encoding --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index fbfd884cee7e1..c9c75cd8c2f8e 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -596,9 +596,7 @@ class _Pool_P16 psel> : InstSize16 { let Inst{15-10} = {psel{4...2}, 0b1, psel{1...0}}; } -class _Pool_P16_MV psel> : _Pool_P16<0b00000> { - let Inst{9...5} = psel; -} +class _Pool_P16_MV : _Pool_P16<0b00000>; class _Pool_P16_SR psel> : _Pool_P16<0b00011> { let Inst{8} = psel; @@ -647,8 +645,9 @@ class _Pool_P16_BR psel> : _Pool_P16<0b11010> { let Inst{3...0} = psel; } -class _Pool_P16_RI psel> : _Pool_P16_MV<0b00000> { +class _Pool_P16_RI psel> : _Pool_P16_MV { let Inst{4...3} = psel; + let Inst{9...5} = 0b00000; } class _Pool_P16_SYSCALL psel> : _Pool_P16_RI<0b01> { @@ -1843,7 +1842,7 @@ class BBit_Enc isel> : _Pool_P_BRI let Inst{0} = offset{11}; } -class MOVE_Enc isel> : _Pool_P16 +class MOVE_Enc : _Pool_P16_MV { bits<5> rt; bits<5> rs; @@ -2144,7 +2143,7 @@ def LWPC_NM : LoadPCBase, Op48_Enc<0b01111> let isMoveReg = 1 in { def MOVE16_NM : InstNM<(outs GPRNM32NZOpnd:$rt), (ins GPRNM32Opnd:$rs), - "move\t$rt, $rs", []>, MOVE_Enc<0b00100>; + "move\t$rt, $rs", []>, MOVE_Enc; def MOVEP_NM : InstNM<(outs GPRNM2R1Opnd:$dst1, GPRNM2R2Opnd:$dst2), (ins GPRNM4ZOpnd:$src1, GPRNM4ZOpnd:$src2), From caca28e4326b75e1392bbb355de8fd112012b775 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 17 Jan 2023 20:37:51 +0530 Subject: [PATCH 076/123] Refactor Li_NM to LI48_NM --- llvm/lib/Target/Mips/MipsSEFrameLowering.cpp | 2 +- llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 2 +- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp index e762e5c6dc9f5..369e94509a951 100644 --- a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -546,7 +546,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF, int64_t MaxAlign = -(int64_t)MFI.getMaxAlign().value(); if (ABI.IsP32()) - BuildMI(MBB, MBBI, dl, TII.get(Mips::Li_NM), VR).addImm(MaxAlign); + BuildMI(MBB, MBBI, dl, TII.get(Mips::LI48_NM), VR).addImm(MaxAlign); else BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR) .addReg(ZERO) diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index 75ac31e31c883..1961837dbd610 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -659,7 +659,7 @@ unsigned MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); const TargetRegisterClass *RC = &Mips::GPRNM32RegClass; Register Reg = RegInfo.createVirtualRegister(RC); - BuildMI(MBB, II, DL, get(Mips::Li_NM), Reg).addImm((int32_t)Imm); + BuildMI(MBB, II, DL, get(Mips::LI48_NM), Reg).addImm((int32_t)Imm); return Reg; } diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index d0c653b45fb80..463c2316c5050 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -122,7 +122,7 @@ def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, EXTW_NM, INS_NM, LA_NM, - Li_NM, LAGPB_NM, LUI_NM, LI16_NM, + LI48_NM, LAGPB_NM, LUI_NM, LI16_NM, LSA_NM, MOVEP_NM, MOVE16_NM, MOD_NM, MODU_NM, MOVEPREV_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index c9c75cd8c2f8e..9ad87bc587195 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1589,9 +1589,9 @@ def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { def LI16_NM : LoadImmediateNM<"li", GPRNM3Opnd, nimm7_nm, imm7M1To126>, - LI16_Enc<0b11000>; -def Li_NM : LoadAddressAbsNM<"li", GPRNM32Opnd, sym32_abs_nm, - addrpcrel>, Op48_Enc<0b00000>; + LI16_Enc<0b11000>; +def LI48_NM : LoadAddressAbsNM<"li", GPRNM32Opnd, sym32_abs_nm, + addrpcrel>, Op48_Enc<0b00000>; def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM32Opnd, sym32_gp_nm, addrgprel>, Op48_Enc<0b00010>; } // isReMaterializable = 1 @@ -1688,7 +1688,7 @@ let hasPostISelHook = 1, isCall = 1, isCTI = 1, Defs = [RA_NM] in { PseudoInstExpansion<(JALRC_NM RA_NM, GPRNM32Opnd:$rs)>; } -def : NMPat<(i32 imm32_NM:$imm), (Li_NM imm:$imm)>; +def : NMPat<(i32 imm32_NM:$imm), (LI48_NM imm:$imm)>; def : NMPat<(MipsFullAddr tglobaltlsaddr:$in), (LA_NM tglobaltlsaddr:$in)>; def : NMPat<(MipsFullAddr tblockaddress:$in), (LA_NM tblockaddress:$in)>; From a48e6ad6afbbe21be6627944a56e887cefe28667 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 17 Jan 2023 20:39:52 +0530 Subject: [PATCH 077/123] Fix order of operands in TEQ/TNE description --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 9ad87bc587195..7e04b59d8c397 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -911,7 +911,7 @@ class ExtInsBase_Enc isel> : _Pool_P_EXT_INS { class Trap_Desc : InstNM<(outs), (ins RO:$rs, RO:$rt, ImmOp:$imm), - !strconcat(opstr, "\t$rt, $rs, $imm"), []> { + !strconcat(opstr, "\t$rs, $rt, $imm"), []> { let hasSideEffects = 1; let isCTI = 1; } From 311b489214846b8b66c60427efa2b69904a9c6df Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 17 Jan 2023 21:14:22 +0530 Subject: [PATCH 078/123] Fix immediate operand type for ANDI[32] --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 7e04b59d8c397..1b7a2b6066c48 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -185,7 +185,7 @@ class NMUImmScaledAsmOperandClass { let PrintMethod = "printUImm<12>"; - let ParserMatchClass = !cast("UImm12AsmOperandClass"); + let ParserMatchClass = NMUImmAsmOperandClass<12>; } def uimm12s3_nm : Operand { @@ -1522,7 +1522,7 @@ def ORI_NM : CondLogicI32_Desc<"ori", uimm12_nm, GPRNM32Opnd, imm32ZExt12, or> CondLogicI32_Enc<0b0000>; def XORI_NM : CondLogicI32_Desc<"xori", uimm12_nm, GPRNM32Opnd, imm32ZExt12, xor>, CondLogicI32_Enc<0b0001>; -def ANDI_NM : CondLogicI32_Desc<"andi", uimm16, GPRNM32Opnd, imm32ZExt12ANDI, and>, +def ANDI_NM : CondLogicI32_Desc<"andi", uimm12_nm, GPRNM32Opnd, imm32ZExt12ANDI, and>, CondLogicI32_Enc<0b0010>; def SLTI_NM : CondLogicI32_Desc<"slti", uimm12_nm, GPRNM32Opnd, imm32ZExt12, setlt>, CondLogicI32_Enc<0b0100>; From a2fdcba1d21943ad8fff2b3f2d95624f0adf66c3 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 21 Jan 2023 11:41:23 +0530 Subject: [PATCH 079/123] Refactor and re-order register class heirarchies --- llvm/lib/Target/Mips/MipsRegisterInfo.td | 137 ++++++++-------------- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 54 ++++----- 2 files changed, 78 insertions(+), 113 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index d59114df69917..cb8924545b193 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -635,74 +635,14 @@ def GPRMM16AsmOperand : MipsAsmRegOperand { let PredicateMethod = "isMM16AsmReg"; } -class GPRNM32AsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM32AsmReg"; - let PredicateMethod = "isGPRNMAsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; -} - -class GPRNM16AsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM16AsmReg"; - let PredicateMethod = "isGPRNMAsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; - let SuperClasses = Supers; -} - -class GPRNMSPAsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNMSPAsmReg"; - let PredicateMethod = "isGPRNMAsmReg"; +class GPRNMAsmOperandClass Supers = []> : MipsAsmRegOperand { + let Name = "GPRNM" # Cname; + let PredicateMethod = "isGPRNMAsmReg"; let RenderMethod = "addGPRNM32AsmRegOperands"; let SuperClasses = Supers; } -class GPRNMGPAsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNMGPAsmReg"; - let PredicateMethod = "isGPRNMAsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; - let SuperClasses = Supers; -} - -def GPRNMGPAsmOperand : GPRNMGPAsmOperandClass; - -class GPRNM16ZeroAsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM16ZeroAsmReg"; - let PredicateMethod = "isGPRNMAsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; - let SuperClasses = Supers; -} - -//def GPRNM16ZeroAsmOperand : GPRNM16ZeroAsmOperandClass; - -class GPRNM4x4AsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM4x4AsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; - let PredicateMethod = "isGPRNMAsmReg"; -} - -class GPRNM4x4ZeroAsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM4x4ZeroAsmReg"; - let PredicateMethod = "isGPRNMAsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; -} - -class GPRNM32NZAsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNMNonZeroAsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; - let PredicateMethod = "isGPRNMAsmReg"; -} - -class GPRNM2R1AsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM2R1AsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; - let PredicateMethod = "isGPRNMAsmReg"; -} - -class GPRNM2R2AsmOperandClass Supers = []> : MipsAsmRegOperand { - let Name = "GPRNM2R2AsmReg"; - let RenderMethod = "addGPRNM32AsmRegOperands"; - let PredicateMethod = "isGPRNMAsmReg"; -} - def GPRMM16AsmOperandZero : MipsAsmRegOperand { let Name = "GPRMM16AsmRegZero"; let PredicateMethod = "isMM16AsmRegZero"; @@ -796,46 +736,71 @@ def GPR32Opnd : RegisterOperand { let ParserMatchClass = GPR32AsmOperand; } -def GPRNMGPOpnd : RegisterOperand { - let ParserMatchClass = GPRNMGPAsmOperand; +def GPRNM48Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"48Reg5", "GPRNM32RegClassID", + []>; } -def GPRNMSPOpnd : RegisterOperand { - let ParserMatchClass = GPRNMSPAsmOperandClass<[GPRNMGPOpnd.ParserMatchClass]>; +def GPRNM32NZOpnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"32Reg5NZ", "GPRNM32NZRegClassID", + [GPRNM48Opnd.ParserMatchClass]>; } -def GPRNM3Opnd : RegisterOperand { - let ParserMatchClass = GPRNM16AsmOperandClass<[GPRNMSPOpnd.ParserMatchClass]>; +def GPRNM32Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"32Reg5", "GPRNM32RegClassID", + [GPRNM32NZOpnd.ParserMatchClass]>; } -def GPRNM3ZOpnd : RegisterOperand { - let ParserMatchClass = GPRNM16ZeroAsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; +def GPRNM4Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"16Reg4x4", "GPRNM4RegClassID", + [GPRNM32Opnd.ParserMatchClass]>; + let EncoderMethod = "getGPRNM4x4Reg"; } -def GPRNM2R1Opnd : RegisterOperand { - let ParserMatchClass = GPRNM2R1AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; +def GPRNM4ZOpnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"16Reg4x4Z", "GPRNM4ZRegClassID", + [GPRNM32Opnd.ParserMatchClass]>; + let EncoderMethod = "getGPRNM4x4ZeroReg"; } -def GPRNM2R2Opnd : RegisterOperand { - let ParserMatchClass = GPRNM2R2AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; +def GPRNM16R5Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"16Reg5", "GPRNM32RegClassID", + [GPRNM4Opnd.ParserMatchClass]>; } -def GPRNM4Opnd : RegisterOperand { - let ParserMatchClass = GPRNM4x4AsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; - let EncoderMethod = "getGPRNM4x4Reg"; +def GPRNM16R5NZOpnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"16Reg5NZ", "GPRNM32NZRegClassID", + [GPRNM4Opnd.ParserMatchClass]>; } -def GPRNM4ZOpnd : RegisterOperand { - let ParserMatchClass = GPRNM4x4ZeroAsmOperandClass<[GPRNM3Opnd.ParserMatchClass]>; - let EncoderMethod = "getGPRNM4x4ZeroReg"; +def GPRNM16R3Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"16Reg3", "GPRNM3RegClassID", + [GPRNM16R5Opnd.ParserMatchClass]>; } -def GPRNM32NZOpnd : RegisterOperand { - let ParserMatchClass = GPRNM32NZAsmOperandClass<[GPRNM4Opnd.ParserMatchClass]>; +def GPRNM16R3ZOpnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"16Reg3Z", "GPRNM3ZRegClassID", + [GPRNM16R5Opnd.ParserMatchClass]>; } -def GPRNM32Opnd : RegisterOperand { - let ParserMatchClass = GPRNM32AsmOperandClass<[GPRNM32NZOpnd.ParserMatchClass]>; +def GPRNMSPOpnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"RegSP", "GPRNMSPRegClassID", + [GPRNM16R3Opnd.ParserMatchClass]>; +} + +def GPRNMGPOpnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"RegGP", "GPRNMGPRegClassID", + [GPRNM16R3Opnd.ParserMatchClass]>; +} + +def GPRNM2R1Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"2Reg1", "GPRNM2R1RegClassID", + [GPRNM4Opnd.ParserMatchClass]>; +} + +def GPRNM2R2Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"2Reg2", "GPRNM2R2RegClassID", + [GPRNM4Opnd.ParserMatchClass]>; } def GPRMM16Opnd : RegisterOperand { diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 1b7a2b6066c48..326e7122241b6 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1507,9 +1507,9 @@ def SOV_NM : ArithLogicR32_Desc<"sov", GPRNM32Opnd>, // 16-bit register operations let FastISelShouldIgnore = 1, isCommutable=1 in { -def SUBu16_NM : AddSubR16_Desc<"subu", GPRNM3Opnd, sub>, +def SUBu16_NM : AddSubR16_Desc<"subu", GPRNM16R3Opnd, sub>, AddSubR16_Enc<0b1>; -def ADDu16_NM : AddSubR16_Desc<"addu", GPRNM3Opnd, add>, +def ADDu16_NM : AddSubR16_Desc<"addu", GPRNM16R3Opnd, add>, AddSubR16_Enc<0b0>; def ADDu4x4_NM : Arith4x4_Desc<"addu", GPRNM4Opnd, add>, Arith4x4_Enc<0b00>; @@ -1534,11 +1534,11 @@ def SEQI_NM : CondLogicI32_Desc<"seqi", uimm12_nm, GPRNM32Opnd, imm32ZExt12, se // P.SHIFT pool of instructions def SLL_NM : ShiftI_Desc<"sll", uimm5_nm, GPRNM32Opnd, imm32ZExt5, shl>, ShiftI32_Enc<0b0000>; -def SLL16_NM : ShiftI_Desc<"sll", uimm3shift_nm, GPRNM3Opnd, imm32ZExt3, shl>, +def SLL16_NM : ShiftI_Desc<"sll", uimm3shift_nm, GPRNM16R3Opnd, imm32ZExt3, shl>, ShiftI16_Enc<0b0>; def SRL_NM : ShiftI_Desc<"srl", uimm5_nm, GPRNM32Opnd, imm32ZExt5, srl>, ShiftI32_Enc<0b0010>; -def SRL16_NM : ShiftI_Desc<"srl", uimm3shift_nm, GPRNM3Opnd, imm32ZExt3, srl>, +def SRL16_NM : ShiftI_Desc<"srl", uimm3shift_nm, GPRNM16R3Opnd, imm32ZExt3, srl>, ShiftI16_Enc<0b1>; def SRA_NM : ShiftI_Desc<"sra", uimm5_nm, GPRNM32Opnd, imm32ZExt5, sra>, ShiftI32_Enc<0b0100>; @@ -1550,10 +1550,10 @@ def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPRNM32NZOpnd, GPRNM32Opnd, imm32SExt12OrZExt16, add>; -def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPRNM32Opnd, +def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPRNM48Opnd, imm32_NM, add>, Op48_Enc<0b00001>; -def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPRNM32Opnd, sym32_pc_nm, +def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPRNM48Opnd, sym32_pc_nm, addrpcrel>, Op48_Enc<0b00011>; def LSA_NM : LoadScaledAddressNM<"lsa", GPRNM32Opnd>, LoadScaledAddress_Enc; @@ -1571,15 +1571,15 @@ def BYTEREVW_NM : ReverseNM<"byterevw", GPRNM32Opnd, bswap>; def TEQ_NM : Trap_Desc<"teq", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b0>; def TNE_NM : Trap_Desc<"tne", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b1>; -def NOT16_NM : ArithLogicR16U_Desc<"not", GPRNM3Opnd, not>, +def NOT16_NM : ArithLogicR16U_Desc<"not", GPRNM16R3Opnd, not>, ArithLogicR16_Enc<0b00>; def NOT_NM : MipsInstAlias<"not $rt, $rs", (NOR_NM GPRNM32Opnd:$rt, GPRNM32Opnd:$rs, ZERO_NM)>; -def XOR16_NM : ArithLogicR16_Desc<"xor", GPRNM3Opnd>, +def XOR16_NM : ArithLogicR16_Desc<"xor", GPRNM16R3Opnd>, ArithLogicR16_Enc<0b01>; -def AND16_NM : ArithLogicR16_Desc<"and", GPRNM3Opnd>, +def AND16_NM : ArithLogicR16_Desc<"and", GPRNM16R3Opnd>, ArithLogicR16_Enc<0b10>; -def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM3Opnd>, +def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM16R3Opnd>, ArithLogicR16_Enc<0b11>; def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>, IndirectBranch16_Enc<0>; @@ -1588,11 +1588,11 @@ def JALRC16_NM : IndirectBranchNM<"jalrc", GPRNM32Opnd>, IndirectBranch16_Enc<1> def MOVEBALC_NM : MoveBalcBase; let isReMaterializable = 1 in { -def LI16_NM : LoadImmediateNM<"li", GPRNM3Opnd, nimm7_nm, imm7M1To126>, +def LI16_NM : LoadImmediateNM<"li", GPRNM16R3Opnd, nimm7_nm, imm7M1To126>, LI16_Enc<0b11000>; -def LI48_NM : LoadAddressAbsNM<"li", GPRNM32Opnd, sym32_abs_nm, +def LI48_NM : LoadAddressAbsNM<"li", GPRNM48Opnd, sym32_abs_nm, addrpcrel>, Op48_Enc<0b00000>; -def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM32Opnd, sym32_gp_nm, +def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM48Opnd, sym32_gp_nm, addrgprel>, Op48_Enc<0b00010>; } // isReMaterializable = 1 @@ -1611,7 +1611,7 @@ class ANDI16_Enc isel> : _Pool_P16 let Inst{3...0} = imm; } -def ANDI16_NM : ArithLogicINM<"andi", uimm4mask_nm, GPRNM3Opnd, +def ANDI16_NM : ArithLogicINM<"andi", uimm4mask_nm, GPRNM16R3Opnd, imm4Mask, add>, ANDI16_Enc<0b11100>; // Arithmetic and logical instructions with 2 register operands and immediate. @@ -1896,16 +1896,16 @@ class B4_Enc : _Pool_P16<0b11010> { def BEQC_NM : CBranchNM<"beqc", brtarget14_nm, seteq, GPRNM32Opnd>, B14_Enc<0b000>; -def BEQC16_NM : CBranchNM<"beqc16", brtarget4s1_nm, seteq, GPRNM3Opnd>, +def BEQC16_NM : CBranchNM<"beqc16", brtarget4s1_nm, seteq, GPRNM16R3Opnd>, B4_Enc; -def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPRNM3Opnd>, +def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPRNM16R3Opnd>, B14_Enc<0b010>; def BGEUC_NM : CBranchNM<"bgeuc", brtarget14_nm, setuge, GPRNM32Opnd>, B14_Enc<0b011>; def BNEC_NM : CBranchNM<"bnec", brtarget14_nm, setne, GPRNM32Opnd>, B14_Enc<0b100>; -def BNEC16_NM : CBranchNM<"bnec16", brtarget4s1_nm, setne, GPRNM3Opnd>, +def BNEC16_NM : CBranchNM<"bnec16", brtarget4s1_nm, setne, GPRNM16R3Opnd>, B4_Enc; def BLTC_NM : CBranchNM<"bltc", brtarget14_nm, setlt, GPRNM32Opnd>, B14_Enc<0b110>; @@ -2011,27 +2011,27 @@ def LWSP16_NM : LoadMemoryNM16<"lw", GPRNM32Opnd, mem_nm_sp5s2, load, addrsp5s2, LSSPRegMem16_Enc<0b00101>; // Broken def SWSP16_NM : StoreMemoryNM16<"sw", GPRNM32Opnd, mem_nm_sp5s2, store, addrsp5s2, II_SW>, LSSPRegMem16_Enc<0b10101>; // Broken -def LWGP16_NM : LoadMemoryNM16<"lw", GPRNM3Opnd, mem_nm_gp7s2, load, addrgp7s2, II_LW>, +def LWGP16_NM : LoadMemoryNM16<"lw", GPRNM16R3Opnd, mem_nm_gp7s2, load, addrgp7s2, II_LW>, LSGPRegMem16_Enc<0b01001>; -def SWGP16_NM : StoreMemoryNM16<"sw", GPRNM3ZOpnd, mem_nm_gp7s2, store, addrgp7s2, II_SW>, +def SWGP16_NM : StoreMemoryNM16<"sw", GPRNM16R3ZOpnd, mem_nm_gp7s2, store, addrgp7s2, II_SW>, LSGPRegMem16_Enc<0b11001>; -def LW16_NM : LoadMemoryNM16<"lw", GPRNM3Opnd, mem_nm6s2, load, addruimm6s2, II_LW>, +def LW16_NM : LoadMemoryNM16<"lw", GPRNM16R3Opnd, mem_nm6s2, load, addruimm6s2, II_LW>, LSMem16_Enc<0b00001>; -def SW16_NM : StoreMemoryNM16<"sw", GPRNM3ZOpnd, mem_nm6s2, store, addruimm6s2, II_SW>, +def SW16_NM : StoreMemoryNM16<"sw", GPRNM16R3ZOpnd, mem_nm6s2, store, addruimm6s2, II_SW>, LSMem16_Enc<0b10001>; -def LH16_NM : LoadMemoryNM16<"lh", GPRNM3Opnd, mem_nm3s1, sextloadi16, addruimm3s1, II_LH>, +def LH16_NM : LoadMemoryNM16<"lh", GPRNM16R3Opnd, mem_nm3s1, sextloadi16, addruimm3s1, II_LH>, LHMem16_Enc<0b00>; -def LHU16_NM : LoadMemoryNM16<"lhu", GPRNM3Opnd, mem_nm3s1, zextloadi16, addruimm3s1, II_LH>, +def LHU16_NM : LoadMemoryNM16<"lhu", GPRNM16R3Opnd, mem_nm3s1, zextloadi16, addruimm3s1, II_LH>, LHMem16_Enc<0b10>; -def SH16_NM : StoreMemoryNM16<"sh", GPRNM3ZOpnd, mem_nm3s1, truncstorei16, addruimm3s1, II_SH>, +def SH16_NM : StoreMemoryNM16<"sh", GPRNM16R3ZOpnd, mem_nm3s1, truncstorei16, addruimm3s1, II_SH>, LHMem16_Enc<0b01>; -def LB16_NM : LoadMemoryNM16<"lb", GPRNM3Opnd, mem_nm2, sextloadi8, addruimm2, II_LB>, +def LB16_NM : LoadMemoryNM16<"lb", GPRNM16R3Opnd, mem_nm2, sextloadi8, addruimm2, II_LB>, LBMem16_Enc<0b00>; -def LBU16_NM : LoadMemoryNM16<"lbu", GPRNM3Opnd, mem_nm2, zextloadi8, addruimm2, II_LB>, +def LBU16_NM : LoadMemoryNM16<"lbu", GPRNM16R3Opnd, mem_nm2, zextloadi8, addruimm2, II_LB>, LBMem16_Enc<0b10>; -def SB16_NM : StoreMemoryNM16<"sb", GPRNM3ZOpnd, mem_nm2, truncstorei8, addruimm2, II_SB>, +def SB16_NM : StoreMemoryNM16<"sb", GPRNM16R3ZOpnd, mem_nm2, truncstorei8, addruimm2, II_SB>, LBMem16_Enc<0b01>; def LWGP_NM : LoadMemoryNM<"lw", mem_nm_gp19s2, load, addrgp19s2, II_LW>, From 4f2a26c8ea6c2339956fa03552b9f29f0c98964f Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 22 Jan 2023 20:59:59 +0530 Subject: [PATCH 080/123] Fix encoding/decoding for ADDIU variants --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 3 +- .../Mips/Disassembler/MipsDisassembler.cpp | 14 ++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 8 ++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 3 + llvm/lib/Target/Mips/MipsScheduleGeneric.td | 5 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 132 +++++++++++++++--- 6 files changed, 140 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 2d4eaecbb2191..f924b15845d9f 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1393,7 +1393,7 @@ class MipsOperand : public MCParsedAsmOperand { } template bool isNegImm() const { - return (isConstantImm() ? isInt(getConstantImm()) : isImm()) && getConstantImm() < 0; + return (isConstantImm() && getConstantImm() < 0 && isUInt(-getConstantImm())); } template bool isUImm() const { @@ -6258,6 +6258,7 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { case Mips::ADDIU48_NM: case Mips::ADDu4x4_NM: case Mips::MUL4x4_NM: + case Mips::ADDIURS5_NM: if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg()) return Match_RequiresSameSrcAndDst; return Match_Success; diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index ab962df3b771b..9d1a554866aa5 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -636,6 +636,11 @@ static DecodeStatus DecodeNMRegList16Operand(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeNegImm12(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static MCDisassembler *createMipsDisassembler( const Target &T, const MCSubtargetInfo &STI, @@ -3052,3 +3057,12 @@ static DecodeStatus DecodeNMRegList16Operand(MCInst &Inst, (RegStart << 5) | (RegCount << 1), Address, Decoder); } + +static DecodeStatus DecodeNegImm12(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Imm = fieldFromInstruction(Insn, 0, 12); + Inst.addOperand(MCOperand::createImm(-Imm)); + return MCDisassembler::Success; +} diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 46dd82aec5e89..74b41efb594d3 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1598,4 +1598,12 @@ MipsMCCodeEmitter::getNMRegList16Encoding(const MCInst &MI, unsigned OpNo, return res; } +unsigned +MipsMCCodeEmitter::getNegImm12Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + int res = MI.getOperand(OpNo).getImm(); + return (unsigned) -res; +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index bbec68aa329dd..1631130d5c864 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -358,6 +358,9 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getNMRegList16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getNegImm12Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; private: void LowerCompactBranch(MCInst& Inst) const; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 463c2316c5050..95e1cae9ce0b7 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -117,8 +117,9 @@ def : InstRW<[GenericWriteALU], (instrs ADDIUPC_MMR6, ADDIU_MMR6, ADDU16_MMR6, // ============= def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, - ADDiu_NM, ADDIU48_NM, - ADDIUPC48_NM, + ADDiu_NM, ADDIUR2_NM, ADDIURS5_NM, ADDIU48_NM, + ADDIUGPB_NM, ADDIUGPW_NM, ADDIUR1SP_NM, + ADDIUPC48_NM, ADDIUNEG_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, DIV_NM, DIVU_NM, EXT_NM, EXTW_NM, INS_NM, LA_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 326e7122241b6..20c8d53445516 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -40,7 +40,7 @@ def imm32ZExt5 : IntImmLeaf(Imm.getZExtValue()); }]>; def imm32ZExt3 : IntImmLeaf 0 && Imm.getZExtValue() <= 8;}]>; def imm32SExt12 : IntImmLeaf(Imm.getSExtValue()); }]>; -def imm32Neg12 : IntImmLeaf(Imm.getSExtValue()) && Imm.getSExtValue() < 0; }]>; +def imm32Neg12 : IntImmLeaf(Imm.getSExtValue()) && Imm.getSExtValue() < 0; }]>; // True if (N + 1) fits in 12-bit field. def immZExt12Plus1 : PatLeaf<(imm), [{ return isUInt<13>(N->getZExtValue()) && isUInt<12>(N->getZExtValue() + 1); @@ -48,9 +48,6 @@ def immZExt12Plus1 : PatLeaf<(imm), [{ def immZExt7Plus1 : PatLeaf<(imm), [{ return isUInt<8>(N->getZExtValue()) && isUInt<7>(N->getZExtValue() + 1); }]>; -// Immediate range for signed 12-bit -def imm32SExt12OrZExt16 : IntImmLeaf(Imm.getSExtValue()) - || isUInt<16>(Imm.getZExtValue()); }]>; // Immediate range for signed 20-bit upper part def imm32SExt20s12 : IntImmLeaf(Imm.getSExtValue()) && (Imm.getZExtValue() % 4096 == 0); }]>; @@ -60,6 +57,20 @@ def imm7M1To126 : IntImmLeaf= -1 && Imm.getSExtValue() < 127); }]>; +// Immediate range for unsigned 18-bit +def imm32ZExt18 : IntImmLeaf(Imm.getZExtValue());}]>; + +// Immediate range for unsigned 18-bit +def imm32ZExt4 : IntImmLeaf(Imm.getZExtValue());}]>; + +// Immediate range for unsigned 21-bit word-aligned +def imm32ZExt21s2 : IntImmLeaf(Imm.getZExtValue()) && + (Imm.getZExtValue() % 4 == 0); }]>; + +// Immediate range for unsigned 21-bit word-aligned +def imm32ZExt8s2 : IntImmLeaf(Imm.getZExtValue()) && + (Imm.getZExtValue() % 4 == 0); }]>; + // Immediate range for 16-bit AND immediate def imm4Mask : IntImmLeaf= 0 && Imm.getZExtValue() < 11) || @@ -80,10 +91,9 @@ class ConstantSImmRangeAsmOperandClass Supers = []> : AsmOperandClass { let Name = "NegImm" # Bits; - let RenderMethod = "addSImmOperands<" # Bits # ">"; + let RenderMethod = "addSImmOperands<" # 32 # ">"; let PredicateMethod = "isNegImm<" # Bits # ">"; let SuperClasses = Supers; - let DiagnosticType = "SImm" # Bits; } class Imm7AsmOperandClass : AsmOperandClass { @@ -212,8 +222,9 @@ def uimm3plus1_nm : Operand { let ParserMatchClass = NMUImmAsmOperandClass<3, [], 1>; } def nimm12_nm : Operand { - let PrintMethod = "printUImm<12>"; - let ParserMatchClass = !cast("NaImm12AsmOperandClass"); + let ParserMatchClass = !cast("NImm12AsmOperandClass"); + let EncoderMethod = "getNegImm12Encoding"; + let DecoderMethod = "DecodeNegImm12"; } def uimm16_nm : Operand { let PrintMethod = "printUImm<16>"; @@ -223,6 +234,18 @@ def uimm5s1_nm : Operand { let PrintMethod = "printUImm<5>"; let ParserMatchClass = NMUImmScaledAsmOperandClass<4, 1>; } +def uimm5s2_nm : Operand { + let PrintMethod = "printUImm<5>"; + let ParserMatchClass = NMUImmScaledAsmOperandClass<3, 2, [uimm16_nm.ParserMatchClass]>; +} +def uimm21s2_nm : Operand { + let PrintMethod = "printUImm<21>"; + let ParserMatchClass = NMUImmScaledAsmOperandClass<19, 2, [uimm16_nm.ParserMatchClass]>; +} +def uimm8s2_nm : Operand { + let PrintMethod = "printUImm<8>"; + let ParserMatchClass = NMUImmScaledAsmOperandClass<6, 2, [uimm16_nm.ParserMatchClass]>; +} def nimm7_nm : Operand { let ParserMatchClass = !cast("Imm7AsmOperand"); let DecoderMethod = "DecodeImmM1To126"; @@ -802,6 +825,16 @@ class ArithLogicINM2Reg : + InstNM<(outs), (ins DRO:$rt, Od:$imm), + !strconcat(opstr, "\t$rt, $imm"), + [(set DRO:$rt, (OpNode DRO:$rt, imm_type:$imm))]> { + let isReMaterializable = 1; +} + + // Arithmetic and logical instructions with 2 register operands and immediate. class ArithLogicINM : ArithLogicINM; -class AddiU32 : - ArithLogicINM2Reg, _Pool_P32<0b00000> { - bits<5> rt; - bits<5> rs; - bits<16> imm; - let Inst{25...21} = rt; - let Inst{20...16} = rs; - let Inst{15...0} = imm; -} +class AddImmediate : + ArithLogicINM2Reg; class LoadUpperI32, def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; -def ADDiu_NM : AddiU32<"addiu", uimm16_simm12, GPRNM32NZOpnd, GPRNM32Opnd, - imm32SExt12OrZExt16, add>; +def ADDIUGPB_NM : AddImmediate<"addiu", uimm18_nm, GPRNM32Opnd, GPRNMGPOpnd, + imm32ZExt18, add>, _Pool_P_GP_BH<0b011> { + bits<5> rt; + bits<18> imm; + let Inst{25...21} = rt; + let Inst{17...0} = imm; +} + +def ADDIUGPW_NM : AddImmediate<"addiu", uimm21s2_nm, GPRNM32Opnd, GPRNMGPOpnd, + imm32ZExt21s2, add>, _Pool_P_GP_W<0b00> { + bits<5> rt; + bits<21> imm; + let Inst{25...21} = rt; + let Inst{20...2} = imm{20...2}; +} + +def ADDiu_NM : AddImmediate<"addiu", uimm16_nm, GPRNM32NZOpnd, GPRNM32Opnd, + imm32ZExt16, add>, _Pool_P32<0b00000> { + bits<5> rt; + bits<5> rs; + bits<16> imm; + let Inst{25...21} = rt; + let Inst{20...16} = rs; + let Inst{15...0} = imm; +} + +def ADDIUNEG_NM : AddImmediate<"addiu", nimm12_nm, GPRNM32Opnd, GPRNM32Opnd, + imm32Neg12, add>, CondLogicI32_Enc<0b1000>; + +def ADDIUR2_NM : AddImmediate<"addiu", uimm5s2_nm, GPRNM16R3Opnd, GPRNM16R3Opnd, + imm32ZExt5, add>, _Pool_P16_A2<0b0> { + bits<3> rt; + bits<3> rs; + bits<5> imm; + let Inst{9...7} = rt; + let Inst{6...4} = rs; + let Inst{2...0} = imm{4...2}; +} + +class RegConstraint { + string Constraints = C; +} +class NoEncode { + string DisableEncoding = E; +} + +def ADDIURS5_NM : AddImmediate<"addiu", uimm4_nm, GPRNM16R5NZOpnd, GPRNM16R5NZOpnd, + imm32ZExt4, add>, _Pool_P16_A2<0b1>, NoEncode<"$rs"> { + bits<5> rt; + bits<4> imm; + let Inst{9...5} = rt; + let Inst{4} = imm{3}; + let Inst{2...0} = imm{2...0}; + let Constraints = "$rs = $rt"; +} + +def ADDIUR1SP_NM : AddImmediate<"addiu", uimm8s2_nm, GPRNM16R3Opnd, GPRNMSPOpnd, + imm32ZExt8s2, add>, _Pool_P16_A1<0b1> { + bits<3> rt; + bits<8> imm; + let Inst{9...7} = rt; + let Inst{5...0} = imm{7...2}; +} + def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPRNM48Opnd, imm32_NM, add>, Op48_Enc<0b00001>; From beada52ba50216e01d2d7f0cd0bc56cb4564f031 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 28 Jan 2023 12:14:14 +0530 Subject: [PATCH 081/123] More fixes for ADDIU variants * Add source-destination match constraints for arithmetic operations * Enforce source-destination match constraints in checkEarlyTargetMatchPredicate * Set DisableEncoding for implicit operands * Add decoder methods for implicit $gp/$sp operands * Fix encoding and operand for 48-bit immediate operations * Fix immediate operand for ADDIU[RS5] --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 11 +-- .../Mips/Disassembler/MipsDisassembler.cpp | 35 ++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 11 +++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 3 + llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 81 +++++++++++++------ 5 files changed, 110 insertions(+), 31 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index f924b15845d9f..d41bf37863dbd 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -6115,6 +6115,10 @@ MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, return Match_Success; case Mips::DATI: case Mips::DAHI: + case Mips::ADDIURS5_NM: + case Mips::ADDIU48_NM: + case Mips::ADDu4x4_NM: + case Mips::MUL4x4_NM: if (static_cast(*Operands[1]) .isValidForTie(static_cast(*Operands[2]))) return Match_Success; @@ -6255,13 +6259,6 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) return Match_RequiresSameSrcAndDst; return Match_Success; - case Mips::ADDIU48_NM: - case Mips::ADDu4x4_NM: - case Mips::MUL4x4_NM: - case Mips::ADDIURS5_NM: - if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg()) - return Match_RequiresSameSrcAndDst; - return Match_Success; case Mips::MOVEP_NM: if (Inst.getOperand(1).getReg() != Inst.getOperand(0).getReg() + 1) return Match_RequiresDstRegPair; diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 9d1a554866aa5..bd6703ada584e 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -121,6 +121,16 @@ static DecodeStatus DecodeGPRNM4RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRNMSPRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeGPRNMGPRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeGPRNM3ZRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -490,6 +500,9 @@ static DecodeStatus DecodeInsSize(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSimm32(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); @@ -1639,6 +1652,22 @@ static DecodeStatus DecodeGPRNM3RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPRNMSPRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + Inst.addOperand(MCOperand::createReg(Mips::SP_NM)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeGPRNMGPRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + Inst.addOperand(MCOperand::createReg(Mips::GP_NM)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeGPRNM3ZRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -2731,6 +2760,12 @@ static DecodeStatus DecodeInsSize(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeSimm32(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + Inst.addOperand(MCOperand::createImm(Insn)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4)); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 74b41efb594d3..e24aba6b40307 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1606,4 +1606,15 @@ MipsMCCodeEmitter::getNegImm12Encoding(const MCInst &MI, unsigned OpNo, return (unsigned) -res; } +unsigned +MipsMCCodeEmitter::getSImm32Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + assert(MO.isImm() && "getSImm32Encoding expects only an immediate"); + int Res = static_cast(MO.getImm()); + return Res; +} + + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 1631130d5c864..898ea02d7618a 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -361,6 +361,9 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getNegImm12Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getSImm32Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; private: void LowerCompactBranch(MCInst& Inst) const; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 20c8d53445516..137530793b1b6 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -183,6 +183,16 @@ class NMUImmAsmOperandClass Supers = [], + int Offset = 0> : + AsmOperandClass { + let Name = "NMSImm" # Bits # "_" # Offset; + let RenderMethod = "addSImmOperands<" # Bits # ">"; + let PredicateMethod = "isConstantSImm<" # Bits # "," # Offset # ">"; + let SuperClasses = Supers; +} + class NMUImmScaledAsmOperandClass Supers = []> : @@ -210,9 +220,8 @@ def uimm5_nm : Operand { let PrintMethod = "printUImm<5>"; let ParserMatchClass = NMUImmAsmOperandClass<5>; } -def uimm4_nm : Operand { - let PrintMethod = "printUImm<4>"; - let ParserMatchClass = NMUImmAsmOperandClass<4>; +def simm4_nm : Operand { + let ParserMatchClass = NMSImmAsmOperandClass<4>; } def uimm1_nm : Operand { let PrintMethod = "printUImm<1>"; @@ -228,7 +237,7 @@ def nimm12_nm : Operand { } def uimm16_nm : Operand { let PrintMethod = "printUImm<16>"; - let ParserMatchClass = !cast("SImm16AsmOperandClass"); + let ParserMatchClass = !cast("UImm16AsmOperandClass"); } def uimm5s1_nm : Operand { let PrintMethod = "printUImm<5>"; @@ -438,6 +447,12 @@ def sym32_abs_nm : Operand { let ParserMatchClass = SymAsmOperandAbs; } +def simm32_nm : Operand { + let ParserMatchClass = NMSImmAsmOperandClass<32>; + let DecoderMethod = "DecodeSimm32"; + let EncoderMethod = "getSImm32Encoding"; +} + def simm32power2 : IntImmLeaf; def uimm16_simm12 : Operand; @@ -463,6 +478,13 @@ def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N-> SDLoc(N), MVT::i32); }]>; +class RegConstraint { + string Constraints = C; +} +class NoEncode { + string DisableEncoding = E; +} + //===----------------------------------------------------------------------===// // // Instruction Descriptions @@ -1233,6 +1255,14 @@ class Op48_Enc isel> : _Pool_P48I { let Inst{15...0} = addr{31...16}; } +class Op48_Imm_Enc isel> : _Pool_P48I { + bits<5> rt; + bits<32> imm; + let Inst{41...37} = rt; + let Inst{31...16} = imm{15...0}; + let Inst{15...0} = imm{31...16}; +} + class LoadPCBase : InstNM<(outs RO:$rt), (ins MO:$addr), "lwpc\t$rt, $addr", @@ -1538,9 +1568,11 @@ def SUBu16_NM : AddSubR16_Desc<"subu", GPRNM16R3Opnd, sub>, def ADDu16_NM : AddSubR16_Desc<"addu", GPRNM16R3Opnd, add>, AddSubR16_Enc<0b0>; def ADDu4x4_NM : Arith4x4_Desc<"addu", GPRNM4Opnd, add>, - Arith4x4_Enc<0b00>; + Arith4x4_Enc<0b00>, RegConstraint<"$rt = $dst">, + NoEncode<"$rt">; def MUL4x4_NM : Arith4x4_Desc<"mul", GPRNM4Opnd, mul>, - Arith4x4_Enc<0b01>; + Arith4x4_Enc<0b01>, RegConstraint<"$rt = $dst">, + NoEncode<"$rt">; } // P.U12 pool of instructions @@ -1574,16 +1606,18 @@ def ROTR_NM : ShiftI_Desc<"rotr", uimm5_nm, GPRNM32Opnd, imm32ZExt5, rotr>, def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; -def ADDIUGPB_NM : AddImmediate<"addiu", uimm18_nm, GPRNM32Opnd, GPRNMGPOpnd, - imm32ZExt18, add>, _Pool_P_GP_BH<0b011> { +def ADDIUGPB_NM : AddImmediate<"addiu", uimm18_nm, GPRNM32Opnd, + GPRNMGPOpnd, imm32ZExt18, add>, + _Pool_P_GP_BH<0b011>, NoEncode<"$rs"> { bits<5> rt; bits<18> imm; let Inst{25...21} = rt; let Inst{17...0} = imm; } -def ADDIUGPW_NM : AddImmediate<"addiu", uimm21s2_nm, GPRNM32Opnd, GPRNMGPOpnd, - imm32ZExt21s2, add>, _Pool_P_GP_W<0b00> { +def ADDIUGPW_NM : AddImmediate<"addiu", uimm21s2_nm, GPRNM32Opnd, + GPRNMGPOpnd, imm32ZExt21s2, add>, + _Pool_P_GP_W<0b00>, NoEncode<"$rs"> { bits<5> rt; bits<21> imm; let Inst{25...21} = rt; @@ -1613,15 +1647,9 @@ def ADDIUR2_NM : AddImmediate<"addiu", uimm5s2_nm, GPRNM16R3Opnd, GPRNM16R3Opnd, let Inst{2...0} = imm{4...2}; } -class RegConstraint { - string Constraints = C; -} -class NoEncode { - string DisableEncoding = E; -} - -def ADDIURS5_NM : AddImmediate<"addiu", uimm4_nm, GPRNM16R5NZOpnd, GPRNM16R5NZOpnd, - imm32ZExt4, add>, _Pool_P16_A2<0b1>, NoEncode<"$rs"> { +def ADDIURS5_NM : AddImmediate<"addiu", simm4_nm, GPRNM16R5NZOpnd, GPRNM16R5NZOpnd, + imm32ZExt4, add>, _Pool_P16_A2<0b1>, + RegConstraint<"$rs = $rt">, NoEncode<"$rs"> { bits<5> rt; bits<4> imm; let Inst{9...5} = rt; @@ -1630,16 +1658,21 @@ def ADDIURS5_NM : AddImmediate<"addiu", uimm4_nm, GPRNM16R5NZOpnd, GPRNM16R5NZOp let Constraints = "$rs = $rt"; } -def ADDIUR1SP_NM : AddImmediate<"addiu", uimm8s2_nm, GPRNM16R3Opnd, GPRNMSPOpnd, - imm32ZExt8s2, add>, _Pool_P16_A1<0b1> { +def ADDIUR1SP_NM : AddImmediate<"addiu", uimm8s2_nm, GPRNM16R3Opnd, + GPRNMSPOpnd, imm32ZExt8s2, add>, + _Pool_P16<0b01100>, + NoEncode<"$rs"> { bits<3> rt; bits<8> imm; let Inst{9...7} = rt; + let Inst{6} = 0b1; let Inst{5...0} = imm{7...2}; } -def ADDIU48_NM : ArithLogicINM<"addiu", simm32_relaxed, GPRNM48Opnd, - imm32_NM, add>, Op48_Enc<0b00001>; +def ADDIU48_NM : ArithLogicINM<"addiu", simm32_nm, GPRNM48Opnd, + imm32_NM, add>, Op48_Imm_Enc<0b00001>, + RegConstraint<"$rs = $rt">; + def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPRNM48Opnd, sym32_pc_nm, addrpcrel>, Op48_Enc<0b00011>; @@ -1679,7 +1712,7 @@ let isReMaterializable = 1 in { def LI16_NM : LoadImmediateNM<"li", GPRNM16R3Opnd, nimm7_nm, imm7M1To126>, LI16_Enc<0b11000>; def LI48_NM : LoadAddressAbsNM<"li", GPRNM48Opnd, sym32_abs_nm, - addrpcrel>, Op48_Enc<0b00000>; + addrpcrel>, Op48_Imm_Enc<0b00000>; def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM48Opnd, sym32_gp_nm, addrgprel>, Op48_Enc<0b00010>; } // isReMaterializable = 1 From de2dc4b86db742616b18e3e4b850b42fc8b5d8cb Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 27 Jan 2023 17:30:32 +0530 Subject: [PATCH 082/123] Fix BGEC encoding --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 137530793b1b6..6c62f1022d091 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1926,7 +1926,7 @@ class B14_Enc isel> : _Pool_P_BR12 bits<5> rs; bits<15> offset; let Inst{25...21} = rt; - let Inst{20...16} = rt; + let Inst{20...16} = rs; let Inst{13...1} = offset{13...1}; let Inst{0} = offset{14}; } @@ -2019,7 +2019,7 @@ def BEQC_NM : CBranchNM<"beqc", brtarget14_nm, seteq, GPRNM32Opnd>, B14_Enc<0b000>; def BEQC16_NM : CBranchNM<"beqc16", brtarget4s1_nm, seteq, GPRNM16R3Opnd>, B4_Enc; -def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPRNM16R3Opnd>, +def BGEC_NM : CBranchNM<"bgec", brtarget14_nm, setge, GPRNM32Opnd>, B14_Enc<0b010>; def BGEUC_NM : CBranchNM<"bgeuc", brtarget14_nm, setuge, GPRNM32Opnd>, B14_Enc<0b011>; From 45da781c8cdeb859bb230bdc58b448379a7c0370 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 27 Jan 2023 20:47:23 +0530 Subject: [PATCH 083/123] Add MOVE.BALC, 1-bit register types Re-factor getBranchEncoding/DecodeBranchTargetNM functions with a template parameter --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 11 +- .../Mips/Disassembler/MipsDisassembler.cpp | 36 ++--- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 127 +++--------------- .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 24 +--- llvm/lib/Target/Mips/MipsRegisterInfo.td | 9 ++ llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 31 +++-- 6 files changed, 84 insertions(+), 154 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index d41bf37863dbd..42cd2eaec8fda 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1987,6 +1987,12 @@ class MipsOperand : public MCParsedAsmOperand { return (RegIdx.Index >= 5 && RegIdx.Index <= 8); } + bool isNM1R1AsmReg() const { + if (!(isRegIdx() && RegIdx.Kind)) + return false; + return (RegIdx.Index == 4 || RegIdx.Index == 5); + } + enum NM_REG_TYPE { NMR, NMR_NZ, @@ -1995,7 +2001,8 @@ class MipsOperand : public MCParsedAsmOperand { NMR_4, NMR_4Z, NMR_2R1, - NMR_2R2 + NMR_2R2, + NMR_1R1 }; template @@ -2021,6 +2028,8 @@ class MipsOperand : public MCParsedAsmOperand { return isNM2R1AsmReg(); case Mips::GPRNM2R2RegClassID: return isNM2R2AsmReg(); + case Mips::GPRNM1R1RegClassID: + return isNM1R1AsmReg(); default: return (RegIdx.Index < 32); } diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index bd6703ada584e..688223c2ad93f 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -161,6 +161,11 @@ static DecodeStatus DecodeGPRNM2R2RegisterClass(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRNM1R1RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -315,11 +320,7 @@ static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, // DecodeBranchTargetMM - Decode nanoMIPS branch offset, which is // shifted left by 1 bit. -static DecodeStatus DecodeBranchTarget25NM(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder); - +template static DecodeStatus DecodeBranchTargetNM(MCInst &Inst, unsigned Offset, uint64_t Address, @@ -1757,6 +1758,18 @@ static DecodeStatus DecodeGPRNM2R2RegisterClass(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeGPRNM1R1RegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo != 0 && RegNo != 1) + return MCDisassembler::Fail; + RegNo += 4; + unsigned Reg = getReg(Decoder, Mips::GPRNM32RegClassID, RegNo); + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -2658,21 +2671,12 @@ static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, return MCDisassembler::Success; } -static DecodeStatus DecodeBranchTarget25NM(MCInst &Inst, - unsigned Offset, - uint64_t Address, - const void *Decoder) { - int32_t BranchOffset = SignExtend32<25>(Offset << 1); - - Inst.addOperand(MCOperand::createImm(BranchOffset)); - return MCDisassembler::Success; -} - +template static DecodeStatus DecodeBranchTargetNM(MCInst &Inst, unsigned Offset, uint64_t Address, const void *Decoder) { - int32_t BranchOffset = SignExtend32<16>(Offset << 1); + int32_t BranchOffset = SignExtend32(Offset << 1); Inst.addOperand(MCOperand::createImm(BranchOffset)); return MCDisassembler::Success; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index e24aba6b40307..9288b1533e60e 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -262,121 +262,26 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, return 0; } -/// getBranchTargetOpValue - Return binary encoding of the branch -/// target operand. If the machine operand requires relocation, -/// record the relocation and return zero. -unsigned MipsMCCodeEmitter:: -getBranchTarget25OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - - // If the destination is an immediate, divide by 2. - if (MO.isImm()) return MO.getImm() >> 1; - - assert(MO.isExpr() && - "getBranchTargetOpValue expects only expressions or immediates"); - - const MCExpr *FixupExpression = MCBinaryExpr::createAdd( - MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); - Fixups.push_back(MCFixup::create(0, FixupExpression, - MCFixupKind(Mips::fixup_NANOMIPS_PC25_S1))); - return 0; -} - -/// getBranchTarget11OpValue - Return binary encoding of the branch -/// target operand. If the machine operand requires relocation, -/// record the relocation and return zero. -unsigned MipsMCCodeEmitter:: -getBranchTarget11OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - - // If the destination is an immediate, divide by 2. - if (MO.isImm()) return MO.getImm() >> 1; - - assert(MO.isExpr() && - "getBranchTargetOpValue expects only expressions or immediates"); - - const MCExpr *FixupExpression = MCBinaryExpr::createAdd( - MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); - Fixups.push_back(MCFixup::create(0, FixupExpression, - MCFixupKind(Mips::fixup_NANOMIPS_PC11_S1))); - return 0; -} - -/// getBranchTarget11OpValue - Return binary encoding of the branch -/// target operand. If the machine operand requires relocation, -/// record the relocation and return zero. -unsigned MipsMCCodeEmitter:: -getBranchTarget10OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - - // If the destination is an immediate, divide by 2. - if (MO.isImm()) return MO.getImm() >> 1; - - assert(MO.isExpr() && - "getBranchTargetOpValue expects only expressions or immediates"); - - const MCExpr *FixupExpression = MCBinaryExpr::createAdd( - MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); - Fixups.push_back(MCFixup::create(0, FixupExpression, - MCFixupKind(Mips::fixup_NANOMIPS_PC10_S1))); - return 0; -} - -/// getBranchTarget14OpValue - Return binary encoding of the branch -/// target operand. If the machine operand requires relocation, -/// record the relocation and return zero. -unsigned MipsMCCodeEmitter:: -getBranchTarget14OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - - // If the destination is an immediate, divide by 2. - if (MO.isImm()) return MO.getImm() >> 1; - - assert(MO.isExpr() && - "getBranchTargetOpValue expects only expressions or immediates"); - - const MCExpr *FixupExpression = MCBinaryExpr::createAdd( - MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); - Fixups.push_back(MCFixup::create(0, FixupExpression, - MCFixupKind(Mips::fixup_NANOMIPS_PC14_S1))); - return 0; -} - -/// getBranchTarget4OpValue - Return binary encoding of the branch -/// target operand. If the machine operand requires relocation, -/// record the relocation and return zero. -unsigned MipsMCCodeEmitter:: -getBranchTarget4OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - - // If the destination is an immediate, divide by 2. - if (MO.isImm()) return MO.getImm() >> 1; - - assert(MO.isExpr() && - "getBranchTargetOpValue expects only expressions or immediates"); - - const MCExpr *FixupExpression = MCBinaryExpr::createAdd( - MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); - Fixups.push_back(MCFixup::create(0, FixupExpression, - MCFixupKind(Mips::fixup_NANOMIPS_PC4_S1))); - return 0; +static unsigned +getNMRelocForSize(unsigned Size) { + switch (Size) { + default: llvm_unreachable("Unhandled fixup kind!"); + case 25: return Mips::fixup_NANOMIPS_PC25_S1; + case 21: return Mips::fixup_NANOMIPS_PC21_S1; + case 14: return Mips::fixup_NANOMIPS_PC14_S1; + case 11: return Mips::fixup_NANOMIPS_PC11_S1; + case 10: return Mips::fixup_NANOMIPS_PC10_S1; + case 7: return Mips::fixup_NANOMIPS_PC7_S1; + case 4: return Mips::fixup_NANOMIPS_PC4_S1; + } } -/// getBranchTarget7OpValue - Return binary encoding of the branch +/// getBranchTargetOpValue - Return binary encoding of the branch /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. +template unsigned MipsMCCodeEmitter:: -getBranchTarget7OpValueNM(const MCInst &MI, unsigned OpNo, +getBranchTargetOpValueNM(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { const MCOperand &MO = MI.getOperand(OpNo); @@ -390,7 +295,7 @@ getBranchTarget7OpValueNM(const MCInst &MI, unsigned OpNo, const MCExpr *FixupExpression = MCBinaryExpr::createAdd( MO.getExpr(), MCConstantExpr::create(0, Ctx), Ctx); Fixups.push_back(MCFixup::create(0, FixupExpression, - MCFixupKind(Mips::fixup_NANOMIPS_PC7_S1))); + MCFixupKind(getNMRelocForSize(Bits)))); return 0; } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 898ea02d7618a..cff15caa8a58b 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -234,24 +234,12 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; - unsigned getBranchTarget25OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getBranchTarget14OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getBranchTarget11OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getBranchTarget10OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getBranchTarget4OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getBranchTarget7OpValueNM(const MCInst &MI, unsigned OpNo, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; + + template + unsigned getBranchTargetOpValueNM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemEncodingNMImm9(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index cb8924545b193..d17976e09ae77 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -384,6 +384,10 @@ def GPRNM2R2 : RegisterClass<"Mips", [i32], 32, (add A1_NM, A2_NM, A3_NM, A4_NM)>; +def GPRNM1R1 : + RegisterClass<"Mips", [i32], 32, + (add A0_NM, A1_NM)>; + class GPR32Class regTypes> : RegisterClass<"Mips", regTypes, 32, (add // Reserved @@ -803,6 +807,11 @@ def GPRNM2R2Opnd : RegisterOperand { [GPRNM4Opnd.ParserMatchClass]>; } +def GPRNM1R1Opnd : RegisterOperand { + let ParserMatchClass = GPRNMAsmOperandClass<"1Reg1", "GPRNM1R1RegClassID", + [GPRNM4Opnd.ParserMatchClass]>; +} + def GPRMM16Opnd : RegisterOperand { let ParserMatchClass = GPRMM16AsmOperand; } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 6c62f1022d091..34b06307bdf00 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -402,27 +402,27 @@ def mem_nmrx : mem_generic { foreach I = {4, 7, 10, 11, 14, 25} in def brtarget # I # _nm : Operand { - let EncoderMethod = "getBranchTarget" # I # "OpValueNM"; + let EncoderMethod = "getBranchTargetOpValueNM<" # I # ">"; let OperandType = "OPERAND_PCREL"; - let DecoderMethod = "DecodeBranchTargetNM"; + let DecoderMethod = "DecodeBranchTargetNM<" # I # ">"; let ParserMatchClass = NMJumpTargetAsmOperand; } def brtarget4s1_nm : Operand { - let EncoderMethod = "getBranchTarget4OpValueNM"; + let EncoderMethod = "getBranchTargetOpValueNM<4>"; let OperandType = "OPERAND_PCREL"; - let DecoderMethod = "DecodeBranchTargetNM"; + let DecoderMethod = "DecodeBranchTargetNM<4>"; let ParserMatchClass = NMJumpTargetAsmOperand; } -foreach I = {10, 25} in +foreach I = {10, 21, 25} in def calltarget # I # _nm : Operand { - let EncoderMethod = "getBranchTarget" # I # "OpValueNM"; + let EncoderMethod = "getBranchTargetOpValueNM<" # I # ">"; let ParserMatchClass = NMJumpTargetAsmOperand; } def jmptarget_nm : Operand { - let EncoderMethod = "getBranchTarget25OpValueNM"; + let EncoderMethod = "getBranchTargetOpValueNM<25>"; let ParserMatchClass = NMJumpTargetAsmOperand; } @@ -1706,7 +1706,22 @@ def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM16R3Opnd>, def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>, IndirectBranch16_Enc<0>; def JALRC16_NM : IndirectBranchNM<"jalrc", GPRNM32Opnd>, IndirectBranch16_Enc<1>; -def MOVEBALC_NM : MoveBalcBase; +def MOVEBALC_NM : InstNM<(outs GPRNM1R1Opnd:$rd), + (ins GPRNM4ZOpnd:$rt, calltarget21_nm:$addr), + "move.balc\t$rd, $rt, $addr", []>, + _Pool_P32<0b00010> { + let isCall = 1; + let isCTI = 1; + let Defs = [RA_NM]; + bits<5> rt; + bits<1> rd; + bits<22> addr; + let Inst{25} = rt{4}; + let Inst{24} = rd; + let Inst{23...21} = rt{2...0}; + let Inst{20...1} = addr{20...1}; + let Inst{0} = addr{21}; +} let isReMaterializable = 1 in { def LI16_NM : LoadImmediateNM<"li", GPRNM16R3Opnd, nimm7_nm, imm7M1To126>, From 1feed6771044253071c3a2e3a14404173b646b75 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 29 Jan 2023 11:04:16 +0530 Subject: [PATCH 084/123] Retain symbolic relocations in code for nanoMIPS --- .../Mips/MCTargetDesc/MipsAsmBackend.cpp | 23 +++++++++++++++++++ .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 51753dff6124f..b9c4e42a54469 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -716,6 +716,29 @@ bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm, case Mips::fixup_MICROMIPS_TLS_TPREL_HI16: case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: case Mips::fixup_MICROMIPS_JALR: + case Mips::fixup_NANOMIPS_PC25_S1: + case Mips::fixup_NANOMIPS_PC21_S1: + case Mips::fixup_NANOMIPS_PC14_S1: + case Mips::fixup_NANOMIPS_PC11_S1: + case Mips::fixup_NANOMIPS_PC10_S1: + case Mips::fixup_NANOMIPS_PC7_S1: + case Mips::fixup_NANOMIPS_PC4_S1: + case Mips::fixup_NANOMIPS_PCHI20: + case Mips::fixup_NANOMIPS_GOTPC_I32: + case Mips::fixup_NANOMIPS_GOTPC_HI20: + case Mips::fixup_NANOMIPS_TLS_GOTTPREL_PC_I32: + case Mips::fixup_NANOMIPS_COPY: + case Mips::fixup_NANOMIPS_ALIGN: + case Mips::fixup_NANOMIPS_FILL: + case Mips::fixup_NANOMIPS_MAX: + case Mips::fixup_NANOMIPS_INSN32: + case Mips::fixup_NANOMIPS_FIXED: + case Mips::fixup_NANOMIPS_NORELAX: + case Mips::fixup_NANOMIPS_SAVERESTORE: + case Mips::fixup_NANOMIPS_INSN16: + case Mips::fixup_NANOMIPS_JUMPTABLE_LOAD: + case Mips::fixup_NANOMIPS_JALR32: + case Mips::fixup_NANOMIPS_JALR16: return true; } } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 1661221910919..8ed266503c353 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -649,6 +649,10 @@ bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, needsRelocateWithSymbol(Sym, (Type >> 8) & 0xff) || needsRelocateWithSymbol(Sym, (Type >> 16) & 0xff); + // Conservative assumption for NanoMips, let the linker handle it! + if (getEMachine() == ELF::EM_NANOMIPS) + return true; + switch (Type) { default: errs() << Type << "\n"; From 3b6974af708f35243a0108b3e87f2cfde9d860db Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 29 Jan 2023 11:30:02 +0530 Subject: [PATCH 085/123] Generate relocation at 2-byte offset within 48-bit instructions --- llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 9288b1533e60e..76acb49c71bd4 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -677,12 +677,12 @@ getSymPCRel(const MCInst &MI, unsigned OpNo, const MCOperand &MO = MI.getOperand(OpNo); if (MO.isExpr()) { Expr = MO.getExpr(); - Fixups.push_back(MCFixup::create(0, Expr, + Fixups.push_back(MCFixup::create(2, Expr, MCFixupKind(Mips::fixup_NANOMIPS_PC_I32))); } else if (MO.isImm()) { Expr = MCConstantExpr::create(static_cast(MO.getImm()), Ctx); - Fixups.push_back(MCFixup::create(0, Expr, + Fixups.push_back(MCFixup::create(2, Expr, MCFixupKind(Mips::fixup_NANOMIPS_PC_I32))); } return 0; @@ -707,7 +707,7 @@ getSymGPRel(const MCInst &MI, unsigned OpNo, else if (MO.isImm()) Expr = MCConstantExpr::create(static_cast(MO.getImm()), Ctx); - Fixups.push_back(MCFixup::create(0, Expr, + Fixups.push_back(MCFixup::create(2, Expr, MCFixupKind(Mips::fixup_NANOMIPS_GPREL_I32))); return 0; } @@ -718,7 +718,7 @@ getSymAbs(const MCInst &MI, unsigned OpNo, const MCSubtargetInfo &STI) const { const MCOperand &MO = MI.getOperand(OpNo); if (MO.isExpr()) - Fixups.push_back(MCFixup::create(0, MO.getExpr(), + Fixups.push_back(MCFixup::create(2, MO.getExpr(), MCFixupKind(Mips::fixup_NANOMIPS_I32))); else if (MO.isImm()) return MO.getImm(); From 8d4e69986a4302238294dfbacd613af400fde7bf Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 29 Jan 2023 22:55:10 +0530 Subject: [PATCH 086/123] Re-factor LA_NM and LAGPB_NM to ADDIU variants * Fix encodings and encoder methods for 48-bit instructions --- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 7 +-- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 6 +-- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 44 ++++++++++--------- .../Mips/NanoMipsLoadStoreOptimizer.cpp | 3 +- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 76acb49c71bd4..aa31ff822e42a 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -693,13 +693,10 @@ getSymGPRel(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { const MCExpr *Expr; - unsigned RegBits=getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, - STI); - - assert(MI.getOperand(OpNo).isReg() && RegBits == 28); - const MCOperand MO = MI.getOperand(OpNo+1); + const MCOperand MO = MI.getOperand(OpNo); if (MO.isExpr()) { + Expr = MO.getExpr(); const MipsMCExpr *MipsExpr = cast(Expr); assert (MipsExpr->getKind() == MipsMCExpr::MEK_GPREL); Expr = MO.getExpr(); diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 95e1cae9ce0b7..c8fa64634e236 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -119,11 +119,11 @@ def : InstRW<[GenericWriteALU], (instrs ADDIUPC_MMR6, ADDIU_MMR6, ADDU16_MMR6, def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, ADDiu_NM, ADDIUR2_NM, ADDIURS5_NM, ADDIU48_NM, ADDIUGPB_NM, ADDIUGPW_NM, ADDIUR1SP_NM, - ADDIUPC48_NM, ADDIUNEG_NM, + ADDIUPC48_NM, ADDIUNEG_NM, ADDIUGP48_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI16_NM, ANDI_NM, BITREVW_NM, BYTEREVW_NM, CLO_NM, CLZ_NM, - DIV_NM, DIVU_NM, EXT_NM, EXTW_NM, INS_NM, LA_NM, - LI48_NM, LAGPB_NM, LUI_NM, LI16_NM, + DIV_NM, DIVU_NM, EXT_NM, EXTW_NM, INS_NM, + LI48_NM, LUI_NM, LI16_NM, LSA_NM, MOVEP_NM, MOVE16_NM, MOD_NM, MODU_NM, MOVEPREV_NM, MUH_NM, MUHU_NM, MUL_NM, MULU_NM, MUL4x4_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 34b06307bdf00..06d1f2da1d24d 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1247,7 +1247,7 @@ class StoreMemoryNM4x4 isel> : _Pool_P48I { +class Op48_Addr_Enc isel> : _Pool_P48I { bits<5> rt; bits<32> addr; let Inst{41...37} = rt; @@ -1485,15 +1485,16 @@ class ReverseNM: InstNM<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), [(set RO:$rd, (OpNode RO:$rs))]>, InstSize32; -class LoadAddressPCRelNM : +class LoadAddressPCRelNM : InstNM<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), [(set RO:$rt, Addr:$addr)]>; class LoadAddressGPRelNM : - InstNM<(outs RO:$rt), (ins MO:$addr), - !strconcat(opstr, "\t$rt, $addr"), - [(set RO:$rt, Addr:$addr)]>; + InstNM<(outs RO:$rt), (ins GPRNMGPOpnd:$rs, MO:$addr), + !strconcat(opstr, "\t$rt, $rs, $addr"), + [(set RO:$rt, (add GPRNMGPOpnd:$rs, Addr:$addr))]>; class LoadAddressAbsNM : InstNM<(outs RO:$rt), (ins MO:$addr), @@ -1673,9 +1674,11 @@ def ADDIU48_NM : ArithLogicINM<"addiu", simm32_nm, GPRNM48Opnd, imm32_NM, add>, Op48_Imm_Enc<0b00001>, RegConstraint<"$rs = $rt">; +def ADDIUPC48_NM : LoadAddressPCRelNM<"addiupc", GPRNM48Opnd, sym32_pc_nm, + addrpcrel>, Op48_Addr_Enc<0b00011>; -def ADDIUPC48_NM : LoadAddressPCRelNM<"addiu", GPRNM48Opnd, sym32_pc_nm, - addrpcrel>, Op48_Enc<0b00011>; +def LAPC_NM : MipsInstAlias<"lapc $rt, $addr", + (ADDIUPC48_NM GPRNM32Opnd: $rt, sym32_pc_nm:$addr)>; def LSA_NM : LoadScaledAddressNM<"lsa", GPRNM32Opnd>, LoadScaledAddress_Enc; @@ -1728,14 +1731,15 @@ def LI16_NM : LoadImmediateNM<"li", GPRNM16R3Opnd, nimm7_nm, imm7M1To126>, LI16_Enc<0b11000>; def LI48_NM : LoadAddressAbsNM<"li", GPRNM48Opnd, sym32_abs_nm, addrpcrel>, Op48_Imm_Enc<0b00000>; -def LAGPB_NM : LoadAddressGPRelNM<"addiu", GPRNM48Opnd, sym32_gp_nm, - addrgprel>, Op48_Enc<0b00010>; +def ADDIUGP48_NM : LoadAddressGPRelNM<"addiu.b32", GPRNM48Opnd, sym32_gp_nm, + addrgprel>, Op48_Addr_Enc<0b00010>; } // isReMaterializable = 1 -let isReMaterializable = 1,isCodeGenOnly = 1 in { -def LA_NM : RegImm48_Desc<"la", simm32_relaxed, GPRNM32Opnd>, - Op48_Enc<0b00011>; -} +def ADDIUB32_NM : MipsInstAlias<"addiu.b32 $rt, $rs, $addr", + (ADDIUGP48_NM GPRNM48Opnd:$rt, + GPRNMGPOpnd:$rs, sym32_gp_nm:$addr)>; +def LA_NM : MipsInstAlias<"la $rt, $addr", + (ADDIUPC48_NM GPRNM48Opnd:$rt, sym32_pc_nm:$addr)>; class ANDI16_Enc isel> : _Pool_P16 { @@ -1826,9 +1830,9 @@ let hasPostISelHook = 1, isCall = 1, isCTI = 1, Defs = [RA_NM] in { def : NMPat<(i32 imm32_NM:$imm), (LI48_NM imm:$imm)>; -def : NMPat<(MipsFullAddr tglobaltlsaddr:$in), (LA_NM tglobaltlsaddr:$in)>; -def : NMPat<(MipsFullAddr tblockaddress:$in), (LA_NM tblockaddress:$in)>; -def : NMPat<(MipsFullAddr tjumptable:$in), (LA_NM tjumptable:$in)>; +def : NMPat<(MipsFullAddr tglobaltlsaddr:$in), (ADDIUPC48_NM tglobaltlsaddr:$in)>; +def : NMPat<(MipsFullAddr tblockaddress:$in), (ADDIUPC48_NM tblockaddress:$in)>; +def : NMPat<(MipsFullAddr tjumptable:$in), (ADDIUPC48_NM tjumptable:$in)>; def : NMPat<(not (or GPRNM32:$rs, GPRNM32:$rt)), (NOR_NM GPRNM32:$rs, GPRNM32:$rt)>; @@ -2274,8 +2278,8 @@ def LW4x4_NM : LoadMemoryNM16<"lw", GPRNM4Opnd, mem_nm2s2, load, addruimm2s2, II def SW4x4_NM : StoreMemoryNM4x4<"sw", GPRNM4Opnd, mem_nm2s2, store, addruimm2s2, II_SW>, LSMem4x4_Enc<0b11101>; -def SWPC_NM : StorePCBase, Op48_Enc<0b01011>; -def LWPC_NM : LoadPCBase, Op48_Enc<0b01111>; +def SWPC_NM : StorePCBase, Op48_Addr_Enc<0b01011>; +def LWPC_NM : LoadPCBase, Op48_Addr_Enc<0b01111>; let isMoveReg = 1 in { def MOVE16_NM : InstNM<(outs GPRNM32NZOpnd:$rt), (ins GPRNM32Opnd:$rs), @@ -2378,10 +2382,10 @@ def alignedglobaladdr : PatFrag<(ops), }]>; def : NMPat<(MipsFullAddr alignedglobaladdr:$in), - (LA_NM alignedglobaladdr:$in)>; + (ADDIUPC48_NM alignedglobaladdr:$in)>; def : NMPat<(MipsFullAddr tglobaladdr:$in), - (LAGPB_NM tglobaladdr:$in)>; + (ADDIUGP48_NM GP_NM, tglobaladdr:$in)>; // Atomic load patterns. diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index 0ed80da047fed..79181b8671b3e 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -638,7 +638,8 @@ static bool isLoadStoreShortChar(MachineInstr *MI) { bool NMLoadStoreOpt::generatePCRelative(MachineBasicBlock &MBB) { SmallVector> Candidates; for (auto &MI : MBB) { - if (MI.getOpcode() == Mips::LA_NM || MI.getOpcode() == Mips::LAGPB_NM) { + if (MI.getOpcode() == Mips::ADDIUPC48_NM || + MI.getOpcode() == Mips::ADDIUGP48_NM) { bool IsRedefined = false; bool IsUsedByMultipleMIs = false; MachineInstr *FirstUse = nullptr; From 014554afd9d3055b260dbb778df4495bbc078981 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 30 Jan 2023 16:41:03 +0530 Subject: [PATCH 087/123] Add p32 ABI flag to ELF header --- llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index f8758f6376646..29b15052a4f5e 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -930,6 +930,8 @@ void MipsTargetELFStreamer::finish() { EFlags |= ELF::EF_MIPS_ABI_O32; else if (getABI().IsN32()) EFlags |= ELF::EF_MIPS_ABI2; + else if (getABI().IsP32()) + EFlags |= ELF::E_NANOMIPS_ABI_P32; if (Features[Mips::FeatureGP64Bit]) { if (getABI().IsO32()) From 25e76d2f9601786a98f48a72468cb27ae14b558c Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 5 Feb 2023 21:51:54 +0530 Subject: [PATCH 088/123] Temp fix for no save/restore register list --- llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 3 ++- llvm/lib/Target/Mips/MipsRegisterInfo.cpp | 3 ++- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 8 +++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index aa31ff822e42a..424f7194b13c0 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1487,7 +1487,8 @@ MipsMCCodeEmitter::getNMRegList16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { unsigned res = 0; - if (!MI.getOperand(OpNo).isImm() || MI.getOperand(OpNo).getImm() != 0) { + if (OpNo < MI.getNumOperands() && + (!MI.getOperand(OpNo).isImm() || MI.getOperand(OpNo).getImm() != 0)) { res = 0x10; for (unsigned I = OpNo; I < MI.getNumOperands(); I++) { unsigned Reg = MI.getOperand(I).getReg(); diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp index b95003985ab66..be34ffe91605b 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp @@ -73,7 +73,8 @@ MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, return 0; case Mips::GPR32RegClassID: case Mips::GPR64RegClassID: - case Mips::DSPRRegClassID: { + case Mips::DSPRRegClassID: + case Mips::GPRNM32RegClassID: { const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); return 28 - TFI->hasFP(MF); } diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 06d1f2da1d24d..7eaa2255579f8 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1608,23 +1608,25 @@ def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; def ADDIUGPB_NM : AddImmediate<"addiu", uimm18_nm, GPRNM32Opnd, - GPRNMGPOpnd, imm32ZExt18, add>, + GPRNM32Opnd, imm32ZExt18, add>, _Pool_P_GP_BH<0b011>, NoEncode<"$rs"> { bits<5> rt; bits<18> imm; let Inst{25...21} = rt; let Inst{17...0} = imm; + let DisableEncoding="$rs"; } def ADDIUGPW_NM : AddImmediate<"addiu", uimm21s2_nm, GPRNM32Opnd, - GPRNMGPOpnd, imm32ZExt21s2, add>, + GPRNM32Opnd, imm32ZExt21s2, add>, _Pool_P_GP_W<0b00>, NoEncode<"$rs"> { bits<5> rt; bits<21> imm; let Inst{25...21} = rt; let Inst{20...2} = imm{20...2}; + let DisableEncoding="$rs"; +} } - def ADDiu_NM : AddImmediate<"addiu", uimm16_nm, GPRNM32NZOpnd, GPRNM32Opnd, imm32ZExt16, add>, _Pool_P32<0b00000> { bits<5> rt; From 72c66a084650c0c8c70572c1b310596b15c14579 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 5 Feb 2023 22:01:05 +0530 Subject: [PATCH 089/123] Temp fix - relax register constraints on $gp operand --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 7eaa2255579f8..cf8fa5c9482d4 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1626,7 +1626,7 @@ def ADDIUGPW_NM : AddImmediate<"addiu", uimm21s2_nm, GPRNM32Opnd, let Inst{20...2} = imm{20...2}; let DisableEncoding="$rs"; } -} + def ADDiu_NM : AddImmediate<"addiu", uimm16_nm, GPRNM32NZOpnd, GPRNM32Opnd, imm32ZExt16, add>, _Pool_P32<0b00000> { bits<5> rt; From 21a2d38aae394b2a28ff46de69b69e6ebb108e90 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Thu, 9 Feb 2023 21:54:40 +0530 Subject: [PATCH 090/123] FIXME: show relocation encoding in nanoMIPS instruction byte order --- llvm/lib/MC/MCAsmStreamer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 72f4ee3f33beb..8e4a215d50435 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -2166,7 +2166,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, for (unsigned j = 0; j != Info.TargetSize; ++j) { unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j; assert(Index < Code.size() * 8 && "Invalid offset in fixup!"); - FixupMap[Index] = 1 + i; + FixupMap[(Index + 16) % (Code.size() * 8)] = 1 + i; } } From 8ad9928c572ad0951d5a1ce713317836c6316364 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 11 Feb 2023 18:39:05 +0530 Subject: [PATCH 091/123] Fix module pcrel and linkrelax assembler directives Add front-end and backend handling for module pcrel. Make ELF header flags responsive to linkrelax directive. --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 135 +++++++++++------- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 44 +++++- llvm/lib/Target/Mips/Mips.td | 3 +- llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 2 +- llvm/lib/Target/Mips/MipsSubtarget.cpp | 17 +-- llvm/lib/Target/Mips/MipsSubtarget.h | 1 + llvm/lib/Target/Mips/MipsTargetStreamer.h | 4 + 7 files changed, 138 insertions(+), 68 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 42cd2eaec8fda..430f4ba286508 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -411,6 +411,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool parseDirectiveTpRelDWord(); bool parseDirectiveModule(); bool parseDirectiveModuleFP(); + bool parseDirectiveLinkRelax(); bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, StringRef Directive); @@ -7644,7 +7645,8 @@ bool MipsAsmParser::parseSetNoReorderDirective() { return false; } AssemblerOptions.back()->setNoReorder(); - getTargetStreamer().emitDirectiveSetNoReorder(); + if (!hasNanoMips()) + getTargetStreamer().emitDirectiveSetNoReorder(); Parser.Lex(); // Consume the EndOfStatement. return false; } @@ -8414,6 +8416,14 @@ bool MipsAsmParser::parseDirectiveNaN() { return false; } + +bool MipsAsmParser::parseDirectiveLinkRelax() { + getParser().Lex(); + setModuleFeatureBits(Mips::FeatureRelax, "relax"); + getTargetStreamer().emitDirectiveLinkRelax(); + return false; +} + bool MipsAsmParser::parseDirectiveSet() { const AsmToken &Tok = getParser().getTok(); StringRef IdVal = Tok.getString(); @@ -8453,59 +8463,61 @@ bool MipsAsmParser::parseDirectiveSet() { return parseSetMacroDirective(); if (IdVal == "nomacro") return parseSetNoMacroDirective(); - if (IdVal == "mips16") - return parseSetMips16Directive(); - if (IdVal == "nomips16") - return parseSetNoMips16Directive(); - if (IdVal == "nomicromips") { - clearFeatureBits(Mips::FeatureMicroMips, "micromips"); - getTargetStreamer().emitDirectiveSetNoMicroMips(); - getParser().eatToEndOfStatement(); - return false; - } - if (IdVal == "micromips") { - if (hasMips64r6()) { - Error(Loc, ".set micromips directive is not supported with MIPS64R6"); + if (!hasNanoMips()) { + if (IdVal == "mips16") + return parseSetMips16Directive(); + if (IdVal == "nomips16") + return parseSetNoMips16Directive(); + if (IdVal == "nomicromips") { + clearFeatureBits(Mips::FeatureMicroMips, "micromips"); + getTargetStreamer().emitDirectiveSetNoMicroMips(); + getParser().eatToEndOfStatement(); return false; } - return parseSetFeature(Mips::FeatureMicroMips); - } - if (IdVal == "mips0") - return parseSetMips0Directive(); - if (IdVal == "mips1") - return parseSetFeature(Mips::FeatureMips1); - if (IdVal == "mips2") - return parseSetFeature(Mips::FeatureMips2); - if (IdVal == "mips3") - return parseSetFeature(Mips::FeatureMips3); - if (IdVal == "mips4") - return parseSetFeature(Mips::FeatureMips4); - if (IdVal == "mips5") - return parseSetFeature(Mips::FeatureMips5); - if (IdVal == "mips32") - return parseSetFeature(Mips::FeatureMips32); - if (IdVal == "mips32r2") - return parseSetFeature(Mips::FeatureMips32r2); - if (IdVal == "mips32r3") - return parseSetFeature(Mips::FeatureMips32r3); - if (IdVal == "mips32r5") - return parseSetFeature(Mips::FeatureMips32r5); - if (IdVal == "mips32r6") - return parseSetFeature(Mips::FeatureMips32r6); - if (IdVal == "mips64") - return parseSetFeature(Mips::FeatureMips64); - if (IdVal == "mips64r2") - return parseSetFeature(Mips::FeatureMips64r2); - if (IdVal == "mips64r3") - return parseSetFeature(Mips::FeatureMips64r3); - if (IdVal == "mips64r5") - return parseSetFeature(Mips::FeatureMips64r5); - if (IdVal == "mips64r6") { - if (inMicroMipsMode()) { - Error(Loc, "MIPS64R6 is not supported with microMIPS"); - return false; + if (IdVal == "micromips") { + if (hasMips64r6()) { + Error(Loc, ".set micromips directive is not supported with MIPS64R6"); + return false; + } + return parseSetFeature(Mips::FeatureMicroMips); + } + if (IdVal == "mips0") + return parseSetMips0Directive(); + if (IdVal == "mips1") + return parseSetFeature(Mips::FeatureMips1); + if (IdVal == "mips2") + return parseSetFeature(Mips::FeatureMips2); + if (IdVal == "mips3") + return parseSetFeature(Mips::FeatureMips3); + if (IdVal == "mips4") + return parseSetFeature(Mips::FeatureMips4); + if (IdVal == "mips5") + return parseSetFeature(Mips::FeatureMips5); + if (IdVal == "mips32") + return parseSetFeature(Mips::FeatureMips32); + if (IdVal == "mips32r2") + return parseSetFeature(Mips::FeatureMips32r2); + if (IdVal == "mips32r3") + return parseSetFeature(Mips::FeatureMips32r3); + if (IdVal == "mips32r5") + return parseSetFeature(Mips::FeatureMips32r5); + if (IdVal == "mips32r6") + return parseSetFeature(Mips::FeatureMips32r6); + if (IdVal == "mips64") + return parseSetFeature(Mips::FeatureMips64); + if (IdVal == "mips64r2") + return parseSetFeature(Mips::FeatureMips64r2); + if (IdVal == "mips64r3") + return parseSetFeature(Mips::FeatureMips64r3); + if (IdVal == "mips64r5") + return parseSetFeature(Mips::FeatureMips64r5); + if (IdVal == "mips64r6") { + if (inMicroMipsMode()) { + Error(Loc, "MIPS64R6 is not supported with microMIPS"); + return false; + } + return parseSetFeature(Mips::FeatureMips64r6); } - return parseSetFeature(Mips::FeatureMips64r6); } if (IdVal == "dsp") return parseSetFeature(Mips::FeatureDSP); @@ -8764,6 +8776,7 @@ bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) { /// ::= .module novirt /// ::= .module ginv /// ::= .module noginv +/// ::= .module pcrel bool MipsAsmParser::parseDirectiveModule() { MCAsmParser &Parser = getParser(); MCAsmLexer &Lexer = getLexer(); @@ -8995,6 +9008,21 @@ bool MipsAsmParser::parseDirectiveModule() { return false; } + return false; // parseDirectiveModule has finished successfully. + } else if (Option == "pcrel") { + // clearModuleFeatureBits(Mips::FeatureGINV, "ginv"); + + // If printing assembly, use the recently updated ABI Flags information. + // If generating ELF, don't do anything (the .MIPS.abiflags section gets + // emitted later). + getTargetStreamer().emitDirectiveModulePcRel(); + + // If this is not the end of the statement, report an error. + if (getLexer().isNot(AsmToken::EndOfStatement)) { + reportParseError("unexpected token, expected end of statement"); + return false; + } + return false; // parseDirectiveModule has finished successfully. } else { return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); @@ -9289,6 +9317,11 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { return false; } + if (IDVal == ".linkrelax") { + parseDirectiveLinkRelax(); + return false; + } + if (IDVal == ".mask" || IDVal == ".fmask") { // .mask bitmask, frame_offset // bitmask: One bit for each register used. diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 29b15052a4f5e..c523bc9e5d771 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -868,6 +868,12 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, if (Features[Mips::FeatureNaN2008]) EFlags |= ELF::EF_MIPS_NAN2008; + if (STI.getTargetTriple().getArch() == Triple::ArchType::nanomips) { + Pic = false; + PCRel = false; + Pid = false; + } + MCA.setELFHeaderEFlags(EFlags); } @@ -939,13 +945,25 @@ void MipsTargetELFStreamer::finish() { } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64]) EFlags |= ELF::EF_MIPS_32BITMODE; - // -mplt is not implemented but we should act as if it was - // given. - if (!Features[Mips::FeatureNoABICalls]) - EFlags |= ELF::EF_MIPS_CPIC; + if (STI.getTargetTriple().getArch() != Triple::ArchType::nanomips) { + // -mplt is not implemented but we should act as if it was + // given. + if (!Features[Mips::FeatureNoABICalls]) + EFlags |= ELF::EF_MIPS_CPIC; - if (Pic) - EFlags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC; + if (Pic) + EFlags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC; + } + else { + if (Pic) + EFlags |= ELF::EF_NANOMIPS_PIC; + if (Pid) + EFlags |= ELF::EF_NANOMIPS_PID; + if (PCRel) + EFlags |= ELF::EF_NANOMIPS_PCREL; + if (Features[Mips::FeatureRelax]) + EFlags |= ELF::EF_NANOMIPS_LINKRELAX; + } MCA.setELFHeaderEFlags(EFlags); @@ -1107,6 +1125,20 @@ void MipsTargetELFStreamer::emitDirectiveOptionPic2() { MCA.setELFHeaderEFlags(Flags); } +void MipsTargetELFStreamer::emitDirectiveLinkRelax() { + MCAssembler &MCA = getStreamer().getAssembler(); + unsigned Flags = MCA.getELFHeaderEFlags(); + Flags |= ELF::EF_NANOMIPS_LINKRELAX; + MCA.setELFHeaderEFlags(Flags); +} + +void MipsTargetELFStreamer::emitDirectiveModulePcRel() { + MCAssembler &MCA = getStreamer().getAssembler(); + unsigned Flags = MCA.getELFHeaderEFlags(); + Flags |= ELF::EF_NANOMIPS_PCREL; + MCA.setELFHeaderEFlags(Flags); +} + void MipsTargetELFStreamer::emitDirectiveInsn() { MipsTargetStreamer::emitDirectiveInsn(); MipsELFStreamer &MEF = static_cast(Streamer); diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index e8ed031d9f7aa..2e8bf6262d9e7 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -155,8 +155,7 @@ def FeatureRelax : SubtargetFeature<"relax", "UseLinkerRelax", def FeatureNanoMips : SubtargetFeature<"nanomips", "MipsArchVersion", "NanoMips", - "NanoMips ISA Support [experimental]", - [FeatureRelax]>; + "NanoMips ISA Support [experimental]">; def FeatureNMS1 : SubtargetFeature<"nms1", "MipsArchVersion", "NanoMips", "NanoMips ISA Support [experimental]">; diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index 306a6fcc1a36c..1597efbca8802 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -820,7 +820,7 @@ void MipsAsmPrinter::emitStartOfAsmFile(Module &M) { } if (IsNanoMips) - TS.emitDirectiveLinkRelax(); + TS.emitDirectiveLinkRelax(); if (!IsNanoMips) // NaN: At the moment we only support: diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index 0717b36fe1e98..2b097a6ae68b8 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp @@ -156,16 +156,17 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, if (hasNanoMips()) NoABICalls = true; - - if (!hasNanoMips() && UnalignedLS) - errs() << "warning: '-mload-store-unaligned' is supported only for nanoMIPS" - << "\n"; + else { + if (UnalignedLS) + errs() << "warning: '-mload-store-unaligned' is supported only for nanoMIPS" + << "\n"; - if (NoABICalls && TM.isPositionIndependent() && !hasNanoMips()) - report_fatal_error("position-independent code requires '-mabicalls'"); + if (NoABICalls && TM.isPositionIndependent()) + report_fatal_error("position-independent code requires '-mabicalls'"); - if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32()) - NoABICalls = true; + if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32()) + NoABICalls = true; + } // Set UseSmallSection. UseSmallSection = GPOpt; diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 0d6650deaf76d..ef6c02de2d118 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -291,6 +291,7 @@ class MipsSubtarget : public MipsGenSubtargetInfo { bool isABICalls() const { return !NoABICalls; } bool isFPXX() const { return IsFPXX; } bool isFP64bit() const { return IsFP64bit; } + bool useLinkerRelax() const { return UseLinkerRelax; } bool useOddSPReg() const { return UseOddSPReg; } bool noOddSPReg() const { return !UseOddSPReg; } bool isNaN2008() const { return IsNaN2008bit; } diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h index b5556a699baec..ac11d50e67248 100644 --- a/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -318,6 +318,8 @@ class MipsTargetELFStreamer : public MipsTargetStreamer { bool MicroMipsEnabled; const MCSubtargetInfo &STI; bool Pic; + bool PCRel; + bool Pid; public: bool isMicroMipsEnabled() const { return MicroMipsEnabled; } @@ -345,6 +347,8 @@ class MipsTargetELFStreamer : public MipsTargetStreamer { void emitDirectiveOptionPic0() override; void emitDirectiveOptionPic2() override; void emitDirectiveInsn() override; + void emitDirectiveLinkRelax() override; + void emitDirectiveModulePcRel() override; void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg) override; void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override; From 51b470daeb5775ddd24a6b37165b9ab726f74616 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 11 Feb 2023 20:00:54 +0530 Subject: [PATCH 092/123] Reorder memory operand class heirarchies --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 92 +++++++++++------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index cf8fa5c9482d4..70695f2b17e7e 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -293,7 +293,52 @@ def uimm2_nm : Operand { let ParserMatchClass = UImm2AsmOperand; } -def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID">; +def MemNMGP19S2Parser : NMMemUimmAsmOperand<19,2, + "Mips::GPRNMGPRegClassID">; + +def mem_nm_gp19s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let OperandType = "OPERAND_NM_GPREL21"; + let OperandNamespace = "NanoMips"; + let DecoderMethod = "DecodeMemNM<21,false,Mips::GPRNMGPRegClassID>"; + let ParserMatchClass = MemNMGP19S2Parser; +} + +def mem_nm_gp18 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let DecoderMethod = "DecodeMemNM<18,false,Mips::GPRNMGPRegClassID>"; + let OperandType = "OPERAND_NM_GPREL18"; + let OperandNamespace = "NanoMips"; + let ParserMatchClass = NMMemUimmAsmOperand<18,0,"Mips::GPRNMGPRegClassID">; +} + +def mem_nm_gp17s1 : mem_generic { + let EncoderMethod = "getMemEncodingNMGP"; + let DecoderMethod = "DecodeMemNM<18,false,Mips::GPRNMGPRegClassID>"; + let OperandType = "OPERAND_NM_GPREL18"; + let OperandNamespace = "NanoMips"; + let ParserMatchClass = NMMemUimmAsmOperand<17,1,"Mips::GPRNMGPRegClassID">; +} + +def MemNMU12Parser : NMMemUimmAsmOperand<12,0, + "Mips::GPRNM32RegClassID",[MemNMGP19S2Parser]>; + +def mem_nmu12 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm12"; + let DecoderMethod = "DecodeMemNM<12,false,Mips::GPRNM32RegClassID>"; + let ParserMatchClass = MemNMU12Parser; +} + +def MemNMS9Parser : NMMemSimmAsmOperand<9,0, + "Mips::GPRNM32RegClassID",[MemNMGP19S2Parser]>; + +def mem_nms9 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm9"; + let DecoderMethod = "DecodeMemNM<9,true,Mips::GPRNM32RegClassID>"; + let ParserMatchClass = MemNMS9Parser; +} + +def MemNMGP7S2Parser : NMMemUimmAsmOperand<7,2,"Mips::GPRNMGPRegClassID",[MemNMS9Parser]>; def mem_nm_gp7s2 : mem_generic { let EncoderMethod = "getMemEncodingNMGP"; @@ -345,51 +390,6 @@ def mem_nm2s2 : mem_generic { let DecoderMethod = "DecodeMemNM4x4"; } -def MemNMGP19S2Parser : NMMemUimmAsmOperand<19,2, - "Mips::GPRNMGPRegClassID",[MemNMGP7S2Parser]>; - -def mem_nm_gp19s2 : mem_generic { - let EncoderMethod = "getMemEncodingNMGP"; - let OperandType = "OPERAND_NM_GPREL21"; - let OperandNamespace = "NanoMips"; - let DecoderMethod = "DecodeMemNM<21,false,Mips::GPRNMGPRegClassID>"; - let ParserMatchClass = MemNMGP7S2Parser; -} - -def mem_nm_gp18 : mem_generic { - let EncoderMethod = "getMemEncodingNMGP"; - let DecoderMethod = "DecodeMemNM<18,false,Mips::GPRNMGPRegClassID>"; - let OperandType = "OPERAND_NM_GPREL18"; - let OperandNamespace = "NanoMips"; - let ParserMatchClass = NMMemUimmAsmOperand<18,0,"Mips::GPRNMGPRegClassID",[MemNMGP7S2Parser]>; -} - -def mem_nm_gp17s1 : mem_generic { - let EncoderMethod = "getMemEncodingNMGP"; - let DecoderMethod = "DecodeMemNM<18,false,Mips::GPRNMGPRegClassID>"; - let OperandType = "OPERAND_NM_GPREL18"; - let OperandNamespace = "NanoMips"; - let ParserMatchClass = NMMemUimmAsmOperand<17,1,"Mips::GPRNMGPRegClassID",[MemNMGP7S2Parser]>; -} - -def MemNMU12Parser : NMMemUimmAsmOperand<12,0, - "Mips::GPRNM32RegClassID",[MemNMGP19S2Parser]>; - -def mem_nmu12 : mem_generic { - let EncoderMethod = "getMemEncodingNMImm12"; - let DecoderMethod = "DecodeMemNM<12,false,Mips::GPRNM32RegClassID>"; - let ParserMatchClass = MemNMU12Parser; -} - -def MemNMS9Parser : NMMemSimmAsmOperand<9,0, - "Mips::GPRNM32RegClassID",[MemNMGP19S2Parser]>; - -def mem_nms9 : mem_generic { - let EncoderMethod = "getMemEncodingNMImm9"; - let DecoderMethod = "DecodeMemNM<9,true,Mips::GPRNM32RegClassID>"; - let ParserMatchClass = MemNMS9Parser; -} - def mem_nmpcrel : mem_generic { let EncoderMethod = "getMemEncodingNMImm9"; let ParserMatchClass = MipsMemSimmAsmOperand<9>; From e8efd206481bf120537131f94ec84adb3f8c95b9 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 11 Feb 2023 20:07:30 +0530 Subject: [PATCH 093/123] Change ADDIUPC mnemonic to LAPC to match binutils assembler --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 70695f2b17e7e..3ec7cc6d31074 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1676,7 +1676,7 @@ def ADDIU48_NM : ArithLogicINM<"addiu", simm32_nm, GPRNM48Opnd, imm32_NM, add>, Op48_Imm_Enc<0b00001>, RegConstraint<"$rs = $rt">; -def ADDIUPC48_NM : LoadAddressPCRelNM<"addiupc", GPRNM48Opnd, sym32_pc_nm, +def ADDIUPC48_NM : LoadAddressPCRelNM<"lapc", GPRNM48Opnd, sym32_pc_nm, addrpcrel>, Op48_Addr_Enc<0b00011>; def LAPC_NM : MipsInstAlias<"lapc $rt, $addr", From c3ed07494cc74283bb210a46f9c010de051f9abe Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 11 Feb 2023 20:10:53 +0530 Subject: [PATCH 094/123] Add missing encoding for LEA --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 3ec7cc6d31074..4c8fdf7cd4516 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1779,7 +1779,13 @@ def LUI_NM : RegImmNM<"lui", simm32s12_nm, GPRNM32Opnd, imm32SExt20s12>, LUI_Enc def ALUIPC_NM : RegImmNM<"aluipc", simm32s12_nm, GPRNM32Opnd, imm32SExt20s12>, LUI_Enc<0b1>; -def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPRNM32Opnd>, InstSize32; +def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPRNM32Opnd>, _Pool_P32<0b00000> { + bits<5> rt; + bits<16> addr; + let Inst{25...21} = rt; + let Inst{20...16} = 0b00000; + let Inst{15...0} = addr; +} def RDHWR_NM : ReadHardwareNM, _Pool_POOL32A0_0<0b011100> { From 99cefc7d619e6590eacf6a1fbc31aa61176100af Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 11 Feb 2023 20:57:52 +0530 Subject: [PATCH 095/123] Move base register constraint for $gp/$sp to parser back-end --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 18 +++++++++++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 30 +++++++++++++++---- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 8 ++--- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 430f4ba286508..a918288230971 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -526,6 +526,8 @@ class MipsAsmParser : public MCTargetAsmParser { Match_RequiresSrcRegPair, Match_RequiresFirstOpLT, Match_RequiresFirstOpGE, + Match_RequiresBaseGP, + Match_RequiresBaseSP, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "MipsGenAsmMatcher.inc" #undef GET_OPERAND_DIAGNOSTIC_TYPES @@ -6285,6 +6287,18 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { if (Inst.getOperand(0).getReg() < Inst.getOperand(1).getReg()) return Match_RequiresFirstOpGE; return Match_Success; + case Mips::ADDIUGPB_NM: + case Mips::ADDIUGPW_NM: + case Mips::ADDIUGP48_NM: + if (Inst.getOperand(1).getReg() != Mips::GP_NM) + return Match_RequiresBaseGP; + return Match_Success; + case Mips::SWSP16_NM: + case Mips::LWSP16_NM: + case Mips::ADDIUR1SP_NM: + if (Inst.getOperand(1).getReg() != Mips::SP_NM) + return Match_RequiresBaseSP; + return Match_Success; } uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags; @@ -6516,6 +6530,10 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(ErrorStart, "size plus position are not in the range 33 .. 64", SMRange(ErrorStart, ErrorEnd)); } + case Match_RequiresBaseGP: + return Error(IDLoc, "expected $gp as base register"); + case Match_RequiresBaseSP: + return Error(IDLoc, "expected $sp as base register"); case Match_Sym32: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected symbol"); diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index a00e4f39660c9..27fba08fac8a6 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -578,27 +578,47 @@ bool MipsSEDAGToDAGISel::selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, bool MipsSEDAGToDAGISel::selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, SDValue &Offset) const { - return selectAddrFrameIndexUOffset(Addr, Base, Offset, 19, 2); + bool Retval = selectAddrFrameIndexUOffset(Addr, Base, Offset, 19, 2); + if (Base == CurDAG->getRegister(Mips::GP_NM, MVT::i32)) + return Retval; + else + return false; } bool MipsSEDAGToDAGISel::selectIntAddrUImm17s1(SDValue Addr, SDValue &Base, SDValue &Offset) const { - return selectAddrFrameIndexUOffset(Addr, Base, Offset, 17, 1); + bool Retval = selectAddrFrameIndexUOffset(Addr, Base, Offset, 17, 1); + if (Base == CurDAG->getRegister(Mips::GP_NM, MVT::i32)) + return Retval; + else + return false; } bool MipsSEDAGToDAGISel::selectIntAddrUImm18(SDValue Addr, SDValue &Base, SDValue &Offset) const { - return selectAddrFrameIndexUOffset(Addr, Base, Offset, 18); + bool Retval = selectAddrFrameIndexUOffset(Addr, Base, Offset, 19); + if (Base == CurDAG->getRegister(Mips::GP_NM, MVT::i32)) + return Retval; + else + return false; } bool MipsSEDAGToDAGISel::selectIntAddrUImm7s2(SDValue Addr, SDValue &Base, SDValue &Offset) const { - return selectAddrFrameIndexUOffset(Addr, Base, Offset, 7, 2); + bool Retval = selectAddrFrameIndexUOffset(Addr, Base, Offset, 7, 2); + if (Base == CurDAG->getRegister(Mips::GP_NM, MVT::i32)) + return Retval; + else + return false; } bool MipsSEDAGToDAGISel::selectIntAddrUImm5s2(SDValue Addr, SDValue &Base, SDValue &Offset) const { - return selectAddrFrameIndexUOffset(Addr, Base, Offset, 5, 2); + bool Retval = selectAddrFrameIndexUOffset(Addr, Base, Offset, 5, 2); + if (Base == CurDAG->getRegister(Mips::SP_NM, MVT::i32)) + return Retval; + else + return false; } // A load/store 'x' indexed (reg + reg) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 4c8fdf7cd4516..61a41ea98a034 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1492,9 +1492,9 @@ class LoadAddressPCRelNM; class LoadAddressGPRelNM : - InstNM<(outs RO:$rt), (ins GPRNMGPOpnd:$rs, MO:$addr), + InstNM<(outs RO:$rt), (ins RO:$rs, MO:$addr), !strconcat(opstr, "\t$rt, $rs, $addr"), - [(set RO:$rt, (add GPRNMGPOpnd:$rs, Addr:$addr))]>; + [(set RO:$rt, (add RO:$rs, Addr:$addr))]>; class LoadAddressAbsNM : InstNM<(outs RO:$rt), (ins MO:$addr), @@ -1662,7 +1662,7 @@ def ADDIURS5_NM : AddImmediate<"addiu", simm4_nm, GPRNM16R5NZOpnd, GPRNM16R5NZOp } def ADDIUR1SP_NM : AddImmediate<"addiu", uimm8s2_nm, GPRNM16R3Opnd, - GPRNMSPOpnd, imm32ZExt8s2, add>, + GPRNM32Opnd, imm32ZExt8s2, add>, _Pool_P16<0b01100>, NoEncode<"$rs"> { bits<3> rt; @@ -1739,7 +1739,7 @@ def ADDIUGP48_NM : LoadAddressGPRelNM<"addiu.b32", GPRNM48Opnd, sym32_gp_nm, def ADDIUB32_NM : MipsInstAlias<"addiu.b32 $rt, $rs, $addr", (ADDIUGP48_NM GPRNM48Opnd:$rt, - GPRNMGPOpnd:$rs, sym32_gp_nm:$addr)>; + GPRNM32Opnd:$rs, sym32_gp_nm:$addr)>; def LA_NM : MipsInstAlias<"la $rt, $addr", (ADDIUPC48_NM GPRNM48Opnd:$rt, sym32_pc_nm:$addr)>; From 734a2f1e20321b09844f2aafc146c214d920455b Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 12 Feb 2023 12:08:35 +0530 Subject: [PATCH 096/123] Assembly parser error-handling for PC-relative/GP-relative symbols --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index a918288230971..2afd4be14ec87 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -6535,8 +6535,12 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_RequiresBaseSP: return Error(IDLoc, "expected $sp as base register"); case Match_Sym32: + case Match_Sym32PCRel: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected symbol"); + case Match_Sym32GPRel: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected %gp_rel expression"); } llvm_unreachable("Implement any new match types added!"); From d27cc5def735bb0f0b2ab3e6113c406d8cd44ff2 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 13 Feb 2023 17:46:07 +0530 Subject: [PATCH 097/123] Re-write PC/GP relative address patterns as single operands --- llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 8 ++++-- llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 5 ++-- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 29 +++++++++++++++------ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 5 ++-- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 4 +-- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index afc3a0f793e85..7b80c0139e6f4 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -85,8 +85,12 @@ bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, return false; } -bool MipsDAGToDAGISel::selectAddrSym(SDValue Addr, SDValue &Base, - SDValue &Offset) const { +bool MipsDAGToDAGISel::selectAddrSym(SDValue Addr, SDValue &Base) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectAddrSymGPRel(SDValue Addr, SDValue &Base) const { llvm_unreachable("Unimplemented function."); return false; } diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index e20fe00b40f38..3dbdbc9669ac1 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -62,8 +62,9 @@ class MipsDAGToDAGISel : public SelectionDAGISel { virtual bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset) const; - virtual bool selectAddrSym(SDValue Addr, SDValue &Base, - SDValue &Offset) const; + virtual bool selectAddrSym(SDValue Addr, SDValue &Base) const; + + virtual bool selectAddrSymGPRel(SDValue Addr, SDValue &Base) const; /// Match integer address pattern. virtual bool selectIntAddr(SDValue Addr, SDValue &Base, diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 27fba08fac8a6..032e0436972b6 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -366,15 +366,28 @@ bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, return true; } -bool MipsSEDAGToDAGISel::selectAddrSym(SDValue Addr, SDValue &Base, - SDValue &Offset) const { - return false; - if (Addr.getOpcode() != ISD::TargetExternalSymbol && - Addr.getOpcode() != ISD::TargetGlobalAddress) +bool MipsSEDAGToDAGISel::selectAddrSym(SDValue Addr, SDValue &Base) const { + SDValue Opnd0 = Addr; + if (isa(Opnd0) || isa(Opnd0) || + isa(Opnd0) || isa(Opnd0) || + isa(Opnd0) || + isa(Opnd0)) { + Base = Addr; + return true; + } + else + return false; +} + +bool MipsSEDAGToDAGISel::selectAddrSymGPRel(SDValue Addr, SDValue &Base) const { + SDValue Opnd0 = Addr; + if (isa(Opnd0) || + isa(Opnd0)) { + Base = Addr; + return true; + } + else return false; - Base = Addr; - Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType()); - return true; } bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index 7a45a29257dad..be2bf21ff6f7b 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -53,8 +53,9 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel { bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset) const override; - bool selectAddrSym(SDValue Addr, SDValue &Base, - SDValue &Offset) const override; + bool selectAddrSym(SDValue Addr, SDValue &Base) const override; + + bool selectAddrSymGPRel(SDValue Addr, SDValue &Base) const override; bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const override; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 61a41ea98a034..3d8a3ee61413a 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -471,8 +471,8 @@ def addrgp18 : ComplexPattern; def addrgp17s1 : ComplexPattern; def addrgp7s2 : ComplexPattern; def addrsp5s2 : ComplexPattern; -def addrpcrel : ComplexPattern; -def addrgprel : ComplexPattern; +def addrpcrel : ComplexPattern; +def addrgprel : ComplexPattern; def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N->getZExtValue()), SDLoc(N), MVT::i32); From d0c715f0157dda13b76c56a30fdecb894ed27bd8 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 13 Feb 2023 17:46:46 +0530 Subject: [PATCH 098/123] Fix optimizer to match correct PC and GP-relative addiu syntax This was previously assuming both to have an implicit src operand. As per ISA, the source operand for ADDIUPC is implicit, while that for ADDIU[GP] is explicit. --- llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index 79181b8671b3e..f716981f565d8 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -702,7 +702,7 @@ bool NMLoadStoreOpt::generatePCRelative(MachineBasicBlock &MBB) { for (auto Pair : Candidates) { auto *LA = Pair.first; auto *Use = Pair.second; - auto &Address = LA->getOperand(1); + auto &Address = LA->getOperand((LA->getOpcode() == Mips::ADDIUPC48_NM)? 1 : 2); auto Dst = Use->getOperand(0).getReg(); int64_t Offset = Use->getOperand(2).getImm() + Address.getOffset(); From 66eaf2e16f91239c94f5176cd99794219fd1c22a Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 13 Feb 2023 17:49:29 +0530 Subject: [PATCH 099/123] Temp commit: disable GP-relative target global address Use PC-relative (ADDIUPC) instructions till we can resolve generating correct GP-relative instructions with %gp_rel --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 3d8a3ee61413a..1b250025bb42a 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -2393,8 +2393,7 @@ def : NMPat<(MipsFullAddr alignedglobaladdr:$in), (ADDIUPC48_NM alignedglobaladdr:$in)>; def : NMPat<(MipsFullAddr tglobaladdr:$in), - (ADDIUGP48_NM GP_NM, tglobaladdr:$in)>; - + (ADDIUPC48_NM tglobaladdr:$in)>; // Atomic load patterns. def : NMPat<(atomic_load_8 addr:$a), (LB_NM addr:$a)>; From 5664966c97b6ec94b2f4dec53d78889f3d3b5e86 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 13 Feb 2023 20:14:26 +0530 Subject: [PATCH 100/123] Fix LWPC/SWPC encodings --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 1b250025bb42a..e3224ca5bd285 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -2286,8 +2286,8 @@ def LW4x4_NM : LoadMemoryNM16<"lw", GPRNM4Opnd, mem_nm2s2, load, addruimm2s2, II def SW4x4_NM : StoreMemoryNM4x4<"sw", GPRNM4Opnd, mem_nm2s2, store, addruimm2s2, II_SW>, LSMem4x4_Enc<0b11101>; -def SWPC_NM : StorePCBase, Op48_Addr_Enc<0b01011>; -def LWPC_NM : LoadPCBase, Op48_Addr_Enc<0b01111>; +def SWPC_NM : StorePCBase, Op48_Addr_Enc<0b01111>; +def LWPC_NM : LoadPCBase, Op48_Addr_Enc<0b01011>; let isMoveReg = 1 in { def MOVE16_NM : InstNM<(outs GPRNM32NZOpnd:$rt), (ins GPRNM32Opnd:$rs), From 56f909ee9037f21ee2a583cf7e8e39ba88303a31 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 13 Feb 2023 20:14:57 +0530 Subject: [PATCH 101/123] Restrict address parsing with relocations to valid cases Signed-offset loads & stores don't have valid relocations and neither do any of the 16-bit loads & stores. --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 2afd4be14ec87..241b622916070 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1473,7 +1473,10 @@ class MipsOperand : public MCParsedAsmOperand { return false; if (isConstantMemOff()) return isShiftedUInt(getConstantMemOff()); - return getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + if (ClassID == Mips::GPRNM32RegClassID) + return getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + else + return false; } template (getConstantMemOff()); - return getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); + return false; } bool isMemRx() const { From c6ce0801d2a48bd238c50a959069a549afabfba7 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 17 Feb 2023 20:06:44 +0530 Subject: [PATCH 102/123] Fix 16Zero source operand register range --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 241b622916070..efab574b60fc7 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1960,7 +1960,7 @@ class MipsOperand : public MCParsedAsmOperand { return false; volatile unsigned RegNo = RegIdx.Index; return ((RegNo == 0) || - (RegNo >= 5 && RegNo <= 7) || + (RegNo >= 4 && RegNo <= 7) || (RegNo >= 17 && RegNo <= 19)); } From 6ab1066143b735581992231cd8ba75f55f5b1987 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 18 Feb 2023 06:43:45 +0530 Subject: [PATCH 103/123] Fix offset for [4x4] loads/stores and change suffix from 2s2 to 4s2 --- .../Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 4 ++-- .../Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h | 2 +- llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 2 +- llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 2 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 2 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 14 +++++++------- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 424f7194b13c0..b6cf58efe462b 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -1159,10 +1159,10 @@ getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, } unsigned MipsMCCodeEmitter:: -getMemEncodingNMImm2S2(const MCInst &MI, unsigned OpNo, +getMemEncodingNMImm4S2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { - // Base register is encoded in bits 7-4, offset is encoded in bits 3-0. + // Base register is encoded in bits 8-4, offset is encoded in bits 3-0. assert(MI.getOperand(OpNo).isReg()); unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 4; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index cff15caa8a58b..cea7b49ebb953 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -255,7 +255,7 @@ class MipsMCCodeEmitter : public MCCodeEmitter { unsigned getMemEncodingNMImm2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; - unsigned getMemEncodingNMImm2S2(const MCInst &MI, unsigned OpNo, + unsigned getMemEncodingNMImm4S2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; unsigned getMemEncodingNMGP(const MCInst &MI, unsigned OpNo, diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 7b80c0139e6f4..46de76081a673 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -199,7 +199,7 @@ bool MipsDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, return false; } -bool MipsDAGToDAGISel::selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, +bool MipsDAGToDAGISel::selectIntAddrUImm4s2(SDValue Addr, SDValue &Base, SDValue &Offset) const { llvm_unreachable("Unimplemented function."); return false; diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index 3dbdbc9669ac1..a453d25e06f15 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -117,7 +117,7 @@ class MipsDAGToDAGISel : public SelectionDAGISel { virtual bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, SDValue &Offset) const; - virtual bool selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, + virtual bool selectIntAddrUImm4s2(SDValue Addr, SDValue &Base, SDValue &Offset) const; virtual bool selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 032e0436972b6..0f0e1f6408aac 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -584,7 +584,7 @@ bool MipsSEDAGToDAGISel::selectIntAddrUImm2(SDValue Addr, SDValue &Base, return selectAddrFrameIndexUOffset(Addr, Base, Offset, 2); } -bool MipsSEDAGToDAGISel::selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, +bool MipsSEDAGToDAGISel::selectIntAddrUImm4s2(SDValue Addr, SDValue &Base, SDValue &Offset) const { return selectAddrFrameIndexUOffset(Addr, Base, Offset, 2, 2); } diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index be2bf21ff6f7b..061630debe694 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -118,7 +118,7 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel { bool selectIntAddrUImm2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; - bool selectIntAddrUImm2s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + bool selectIntAddrUImm4s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; bool selectIntAddrUImm19s2(SDValue Addr, SDValue &Base, SDValue &Offset) const override; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index e3224ca5bd285..41d830ee754bb 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -365,7 +365,7 @@ def MemNM3S1Parser : NMMemUimmAsmOperand<3,1,"Mips::GPRNM3RegClassID",[MemNMSP5S2Parser]>; def MemNM2Parser : NMMemUimmAsmOperand<2,0,"Mips::GPRNM3RegClassID",[MemNMSP5S2Parser]>; -def MemNM2S2Parser : +def MemNM4S2Parser : NMMemUimmAsmOperand<2,2,"Mips::GPRNM4RegClassID",[MemNMSP5S2Parser]>; def mem_nm6s2 : mem_generic { @@ -384,9 +384,9 @@ def mem_nm2 : mem_generic { let ParserMatchClass = MemNM2Parser; } -def mem_nm2s2 : mem_generic { - let EncoderMethod = "getMemEncodingNMImm2S2"; - let ParserMatchClass = MemNM2S2Parser; +def mem_nm4s2 : mem_generic { + let EncoderMethod = "getMemEncodingNMImm4S2"; + let ParserMatchClass = MemNM4S2Parser; let DecoderMethod = "DecodeMemNM4x4"; } @@ -465,7 +465,7 @@ def addrindexedlsl2 : ComplexPattern; def addruimm6s2 : ComplexPattern; def addruimm3s1 : ComplexPattern; def addruimm2 : ComplexPattern; -def addruimm2s2 : ComplexPattern; +def addruimm4s2 : ComplexPattern; def addrgp19s2 : ComplexPattern; def addrgp18 : ComplexPattern; def addrgp17s1 : ComplexPattern; @@ -2281,9 +2281,9 @@ def UASW_NM : MipsInstAlias<"uasw $rt, $addr", //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; -def LW4x4_NM : LoadMemoryNM16<"lw", GPRNM4Opnd, mem_nm2s2, load, addruimm2s2, II_LW>, +def LW4x4_NM : LoadMemoryNM16<"lw", GPRNM4Opnd, mem_nm4s2, load, addruimm4s2, II_LW>, LSMem4x4_Enc<0b01101>; -def SW4x4_NM : StoreMemoryNM4x4<"sw", GPRNM4Opnd, mem_nm2s2, store, addruimm2s2, II_SW>, +def SW4x4_NM : StoreMemoryNM4x4<"sw", GPRNM4Opnd, mem_nm4s2, store, addruimm4s2, II_SW>, LSMem4x4_Enc<0b11101>; def SWPC_NM : StorePCBase, Op48_Addr_Enc<0b01111>; From 05fad9ef0bf18f296f79fff861e07234fe1bfcec Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 18 Feb 2023 06:50:23 +0530 Subject: [PATCH 104/123] Specify decode methods for LH[16] and SH[16] offsets --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 41d830ee754bb..662df0529e7b9 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -376,11 +376,13 @@ def mem_nm6s2 : mem_generic { def mem_nm3s1 : mem_generic { let EncoderMethod = "getMemEncodingNMImm3S1"; + let DecoderMethod = "DecodeMemNM<3,false,Mips::GPRNM3RegClassID>"; let ParserMatchClass = MemNM3S1Parser; } def mem_nm2 : mem_generic { let EncoderMethod = "getMemEncodingNMImm2"; + let DecoderMethod = "DecodeMemNM<2,false,Mips::GPRNM3RegClassID>"; let ParserMatchClass = MemNM2Parser; } From f50b92e035b7a6fbd35f750a38dc2a7eaa428073 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 18 Feb 2023 06:58:34 +0530 Subject: [PATCH 105/123] Accept non-immediate GP-relative offsets in isSym32GPRel --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index efab574b60fc7..4832c215a1759 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1617,8 +1617,6 @@ class MipsOperand : public MCParsedAsmOperand { bool isSym32GPRel() const { MCValue Res; bool Success; - if (Kind != k_Immediate) - return false; Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr); if (Success && Res.getRefKind() == MipsMCExpr::MEK_GPREL) From 5e542aae8ab0fd7b268350b4a96324dbb80db462 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sat, 18 Feb 2023 09:39:14 +0530 Subject: [PATCH 106/123] Add ComplexPattern definition for GP-relative address calculations --- llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 17 +++++++++++++ llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 8 ++++++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 27 +++++++++++++++++++++ llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 9 +++++++ llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 19 ++++++++++++--- 5 files changed, 76 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp index 46de76081a673..95e71d4a32056 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -440,3 +440,20 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, } return true; } + +bool MipsDAGToDAGISel::selectOffsetGP18(SDValue Addr, SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectOffsetGP19s2(SDValue Addr, SDValue &Offset) const { + llvm_unreachable("Unimplemented function."); + return false; +} + +bool MipsDAGToDAGISel::selectOffsetGP(SDValue Addr, SDValue &Offset, + unsigned OffsetBits, + unsigned ShiftAmount) const { + llvm_unreachable("Unimplemented function."); + return false; +} diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h index a453d25e06f15..c4b55f5d21497 100644 --- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h @@ -191,6 +191,14 @@ class MipsDAGToDAGISel : public SelectionDAGISel { bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector &OutOps) override; + + // Select a GP-relative offset expressions + virtual bool selectOffsetGP(SDValue Addr, SDValue &Offset, + unsigned OffsetBits, + unsigned ShiftAmount) const; + virtual bool selectOffsetGP18(SDValue Addr, SDValue &Offset) const; + virtual bool selectOffsetGP19s2(SDValue Addr, SDValue &Offset) const; + }; } diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 0f0e1f6408aac..46957de0ed0e5 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -1609,6 +1609,33 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, return true; } +bool MipsSEDAGToDAGISel::selectOffsetGP( + SDValue Addr, SDValue &Offset, unsigned OffsetBits, + unsigned ShiftAmount = 0) const { + if (Addr.getOpcode() == MipsISD::GPRel || + isa(Addr) || + isa(Addr)) { + ConstantSDNode *CN = dyn_cast(Addr.getOperand(0)); + if (isUIntN(OffsetBits + ShiftAmount, CN->getZExtValue())) { + EVT ValTy = Addr.getValueType(); + Offset = + CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ValTy); + return true; + } + } + return false; +} + +bool MipsSEDAGToDAGISel::selectOffsetGP18(SDValue Addr, + SDValue &Offset) const { + return selectOffsetGP(Addr, Offset, 18); +} + +bool MipsSEDAGToDAGISel::selectOffsetGP19s2(SDValue Addr, + SDValue &Offset) const { + return selectOffsetGP(Addr, Offset, 19, 2); +} + FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOpt::Level OptLevel) { return new MipsSEDAGToDAGISel(TM, OptLevel); diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index 061630debe694..1da7756549ef7 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -175,6 +175,15 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel { bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector &OutOps) override; + + // Select a GP-relative offset expressions + bool selectOffsetGP(SDValue Addr, SDValue &Offset, + unsigned OffsetBits, unsigned ShiftAmount) const; + + bool selectOffsetGP18(SDValue Addr, SDValue &Offset) const override; + + bool selectOffsetGP19s2(SDValue Addr, SDValue &Offset) const override; + }; FunctionPass *createMipsSEISelDag(MipsTargetMachine &TM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 662df0529e7b9..2be23447c80b4 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -475,6 +475,8 @@ def addrgp7s2 : ComplexPattern; def addrsp5s2 : ComplexPattern; def addrpcrel : ComplexPattern; def addrgprel : ComplexPattern; +def offsetgp19s2 : ComplexPattern; +def offsetgp18 : ComplexPattern; def Log2XForm : SDNodeXFormgetTargetConstant(Log2_32(N->getZExtValue()), SDLoc(N), MVT::i32); @@ -1609,8 +1611,17 @@ def ROTR_NM : ShiftI_Desc<"rotr", uimm5_nm, GPRNM32Opnd, imm32ZExt5, rotr>, def EXT_NM : ExtBaseNM, ExtInsBase_Enc<0b1111>; def INS_NM : InsBaseNM, ExtInsBase_Enc<0b1110>; -def ADDIUGPB_NM : AddImmediate<"addiu", uimm18_nm, GPRNM32Opnd, - GPRNM32Opnd, imm32ZExt18, add>, +class AddImmediateGP : + InstNM<(outs DRO:$rt), (ins SRO:$rs, Od:$imm), + !strconcat(opstr, "\t$rt, $rs, $imm"), + [(set DRO:$rt, (OpNode SRO:$rs, imm_type:$imm))]> { + let isReMaterializable = 1; +} + +def ADDIUGPB_NM : AddImmediateGP<"addiu", uimm18_nm, GPRNM32Opnd, + GPRNM32Opnd, offsetgp18, add>, _Pool_P_GP_BH<0b011>, NoEncode<"$rs"> { bits<5> rt; bits<18> imm; @@ -1619,8 +1630,8 @@ def ADDIUGPB_NM : AddImmediate<"addiu", uimm18_nm, GPRNM32Opnd, let DisableEncoding="$rs"; } -def ADDIUGPW_NM : AddImmediate<"addiu", uimm21s2_nm, GPRNM32Opnd, - GPRNM32Opnd, imm32ZExt21s2, add>, +def ADDIUGPW_NM : AddImmediateGP<"addiu", uimm21s2_nm, GPRNM32Opnd, + GPRNM32Opnd, offsetgp19s2, add>, _Pool_P_GP_W<0b00>, NoEncode<"$rs"> { bits<5> rt; bits<21> imm; From 92cd4db72f2dd1e61ce44eb1f28285069e60922d Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 21 Feb 2023 14:50:51 +0530 Subject: [PATCH 107/123] Refactor ADDiu_NM to ADDIU_NM --- .../Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 2 +- llvm/lib/Target/Mips/MipsSERegisterInfo.cpp | 2 +- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 2 +- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 26 +++++++++---------- .../Mips/NanoMipsLoadStoreOptimizer.cpp | 8 +++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp index 01b777f53cdb6..56595776ae8ce 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -111,7 +111,7 @@ unsigned MipsABIInfo::GetPtrAdduOp() const { } unsigned MipsABIInfo::GetPtrAddiuOp() const { - return ArePtrs64bit() ? Mips::DADDiu : IsP32() ? Mips::ADDiu_NM : Mips::ADDiu; + return ArePtrs64bit() ? Mips::DADDiu : IsP32() ? Mips::ADDIU_NM : Mips::ADDiu; } unsigned MipsABIInfo::GetPtrSubuOp() const { diff --git a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp index b09b3ddd01e89..331b6308797b4 100644 --- a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -226,7 +226,7 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, LLVM_DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); - if (MI.getOpcode() == Mips::LEA_ADDiu_NM && Offset == 0) { + if (MI.getOpcode() == Mips::LEA_ADDIU_NM && Offset == 0) { auto &MBB = *MI.getParent(); const MipsSEInstrInfo &TII = *static_cast( MBB.getParent()->getSubtarget().getInstrInfo()); diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index c8fa64634e236..50b4632c14db7 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -117,7 +117,7 @@ def : InstRW<[GenericWriteALU], (instrs ADDIUPC_MMR6, ADDIU_MMR6, ADDU16_MMR6, // ============= def : InstRW<[GenericWriteALU], (instrs ADD_NM, ADDu16_NM, ADDu4x4_NM, ADDu_NM, - ADDiu_NM, ADDIUR2_NM, ADDIURS5_NM, ADDIU48_NM, + ADDIU_NM, ADDIUR2_NM, ADDIURS5_NM, ADDIU48_NM, ADDIUGPB_NM, ADDIUGPW_NM, ADDIUR1SP_NM, ADDIUPC48_NM, ADDIUNEG_NM, ADDIUGP48_NM, ALUIPC_NM, AND_NM, AND16_NM, ANDI16_NM, ANDI_NM, diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 2be23447c80b4..993929a52fb70 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1640,7 +1640,7 @@ def ADDIUGPW_NM : AddImmediateGP<"addiu", uimm21s2_nm, GPRNM32Opnd, let DisableEncoding="$rs"; } -def ADDiu_NM : AddImmediate<"addiu", uimm16_nm, GPRNM32NZOpnd, GPRNM32Opnd, +def ADDIU_NM : AddImmediate<"addiu", uimm16_nm, GPRNM32NZOpnd, GPRNM32Opnd, imm32ZExt16, add>, _Pool_P32<0b00000> { bits<5> rt; bits<5> rs; @@ -1792,7 +1792,7 @@ def LUI_NM : RegImmNM<"lui", simm32s12_nm, GPRNM32Opnd, imm32SExt20s12>, LUI_Enc def ALUIPC_NM : RegImmNM<"aluipc", simm32s12_nm, GPRNM32Opnd, imm32SExt20s12>, LUI_Enc<0b1>; -def LEA_ADDiu_NM : EffectiveAddressNM<"addiu", GPRNM32Opnd>, _Pool_P32<0b00000> { +def LEA_ADDIU_NM : EffectiveAddressNM<"addiu", GPRNM32Opnd>, _Pool_P32<0b00000> { bits<5> rt; bits<16> addr; let Inst{25...21} = rt; @@ -2331,25 +2331,25 @@ def MOVEPREV_NM : InstNM<(outs GPRNM4Opnd:$dst1, GPRNM4Opnd:$dst2), // let AddedComplexity = 3 in { def : NMPat<(i32 (extloadi8 (add GPRNM32:$rs, immFitsAddiu32:$imm))), - (LBU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (LBU_NM (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(i32 (zextloadi8 (add GPRNM32:$rs, immFitsAddiu32:$imm))), - (LBU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (LBU_NM (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(i32 (sextloadi8 (add GPRNM32:$rs, immFitsAddiu32:$imm))), - (LB_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (LB_NM (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(i32 (extloadi16 (add GPRNM32:$rs, immFitsAddiu32:$imm))), - (LHU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (LHU_NM (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(i32 (zextloadi16 (add GPRNM32:$rs, immFitsAddiu32:$imm))), - (LHU_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (LHU_NM (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(i32 (sextloadi16 (add GPRNM32:$rs, immFitsAddiu32:$imm))), - (LH_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (LH_NM (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(i32 (load (add GPRNM32:$rs, immFitsAddiu32:$imm))), - (LW_NM (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (LW_NM (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(truncstorei8 GPRNM32:$rt, (add GPRNM32:$rs, immFitsAddiu32:$imm)), - (SB_NM GPRNM32:$rt, (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (SB_NM GPRNM32:$rt, (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(truncstorei16 GPRNM32:$rt, (add GPRNM32:$rs, immFitsAddiu32:$imm)), - (SH_NM GPRNM32:$rt, (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (SH_NM GPRNM32:$rt, (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; def : NMPat<(store GPRNM32:$rt, (add GPRNM32:$rs, immFitsAddiu32:$imm)), - (SW_NM GPRNM32:$rt, (ADDiu_NM GPRNM32:$rs, imm:$imm), 0)>; + (SW_NM GPRNM32:$rt, (ADDIU_NM GPRNM32:$rs, imm:$imm), 0)>; } // AddedComplexity = 3 // Catching out-of-range immediate loads/stores. @@ -2391,7 +2391,7 @@ def : NMPat<(NMUnalignedSH GPRNM32:$rt, GPRNM32:$rs), def : NMPat<(i32 (load (add GP_NM, (MipsGPRel tglobaladdr:$in)))), (LWGP_NM GP_NM, tglobaladdr:$in)>; def : NMPat<(add GP_NM, (MipsGPRel tglobaladdr:$in)), - (ADDiu_NM GP_NM, tglobaladdr:$in)>; + (ADDIU_NM GP_NM, tglobaladdr:$in)>; // GP-relative address diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index f716981f565d8..b073ca54f2037 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -86,7 +86,7 @@ bool NMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) { bool NMLoadStoreOpt::isStackPointerAdjustment(MachineInstr &MI, bool IsRestore) { - if (MI.getOpcode() != Mips::ADDiu_NM) + if (MI.getOpcode() != Mips::ADDIU_NM) return false; Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(1).getReg(); @@ -383,7 +383,7 @@ bool NMLoadStoreOpt::generateSaveOrRestore(MachineBasicBlock &MBB, // In case of save, the offset is subtracted from SP. if (!IsRestore) NewStackOffset = -NewStackOffset; - BuildMI(MBB, InsertBefore, DL, TII->get(Mips::ADDiu_NM), Mips::SP_NM) + BuildMI(MBB, InsertBefore, DL, TII->get(Mips::ADDIU_NM), Mips::SP_NM) .addReg(Mips::SP_NM) .addImm(NewStackOffset); } @@ -574,7 +574,7 @@ static bool isValidUse(MachineInstr *MI, Register Reg) { case Mips::SWs9_NM: case Mips::LW_NM: case Mips::LWs9_NM: - case Mips::ADDiu_NM: + case Mips::ADDIU_NM: case Mips::LH16_NM: case Mips::LHU16_NM: case Mips::SH16_NM: @@ -708,7 +708,7 @@ bool NMLoadStoreOpt::generatePCRelative(MachineBasicBlock &MBB) { assert(Address.isGlobal()); - if (Use->getOpcode() == Mips::ADDiu_NM) { + if (Use->getOpcode() == Mips::ADDIU_NM) { // Move LA to its use to avoid extending the lifetime of Dst MBB.insert(MBBIter(Use), MBB.remove(LA)); From 56e5527ba8d9454ded135b8392bf2c0561607464 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 21 Feb 2023 15:12:29 +0530 Subject: [PATCH 108/123] Change NOT_NM to NOT16_NM in test case (merge with 8ad10e8208c08c) --- llvm/test/CodeGen/Mips/nanomips/not.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/Mips/nanomips/not.ll b/llvm/test/CodeGen/Mips/nanomips/not.ll index eb962db098ff9..bca986223e2d3 100644 --- a/llvm/test/CodeGen/Mips/nanomips/not.ll +++ b/llvm/test/CodeGen/Mips/nanomips/not.ll @@ -2,7 +2,7 @@ define i32 @test_not(i32 %a) { ; CHECK: not $a0, $a0 -; CHECK: NOT_NM +; CHECK: NOT16_NM %not = xor i32 %a, -1 ret i32 %not } From a42d21b0b29498cea0cb02cafeaaf8e2c2141789 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 21 Feb 2023 17:09:07 +0530 Subject: [PATCH 109/123] Fix crash in MOVEP[REV] optimization pass --- llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp index 82305a3fccefe..d6b676f94c88b 100644 --- a/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsMoveOptimizer.cpp @@ -240,7 +240,13 @@ bool NMMoveOpt::generateMoveP(MachineBasicBlock &MBB) { bool Swap = std::get<2>(Tuple); if (Swap) std::swap(Move1, Move2); - BuildMI(MBB, InsertBefore, DL, TII->get(Mips::MOVEP_NM)) + bool Rev= (isInSet(GPR4, Move1->getOperand(0).getReg()) && + isInSet(GPR2REG1, Move1->getOperand(1).getReg()) && + isInSet(GPR4, Move2->getOperand(0).getReg()) && + isInSet(GPR2REG2, Move2->getOperand(1).getReg())); + + BuildMI(MBB, InsertBefore, DL, + TII->get(Rev ? Mips::MOVEPREV_NM : Mips::MOVEP_NM)) .addReg(Move1->getOperand(0).getReg(), RegState::Define) .addReg(Move2->getOperand(0).getReg(), RegState::Define) .addReg(Move1->getOperand(1).getReg()) From 6b34fdd3c9fa4990978abc21a3b0c074ef7d5349 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 21 Feb 2023 19:39:32 +0530 Subject: [PATCH 110/123] Add DAG pattern and instruction alias for LI as ADDIU with $zero --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 12 ++++++++++++ llvm/test/CodeGen/Mips/nanomips/li.ll | 22 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 993929a52fb70..157b64948abc9 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1650,9 +1650,15 @@ def ADDIU_NM : AddImmediate<"addiu", uimm16_nm, GPRNM32NZOpnd, GPRNM32Opnd, let Inst{15...0} = imm; } +def LI_NM : MipsInstAlias<"li $rt, $imm", + (ADDIU_NM GPRNM32NZOpnd:$rt, ZERO_NM, uimm16_nm:$imm)>; + def ADDIUNEG_NM : AddImmediate<"addiu", nimm12_nm, GPRNM32Opnd, GPRNM32Opnd, imm32Neg12, add>, CondLogicI32_Enc<0b1000>; +def LINEG_NM : MipsInstAlias<"li $rt, $imm", + (ADDIUNEG_NM GPRNM32Opnd:$rt, ZERO_NM, nimm12_nm:$imm)>; + def ADDIUR2_NM : AddImmediate<"addiu", uimm5s2_nm, GPRNM16R3Opnd, GPRNM16R3Opnd, imm32ZExt5, add>, _Pool_P16_A2<0b0> { bits<3> rt; @@ -1744,6 +1750,12 @@ def MOVEBALC_NM : InstNM<(outs GPRNM1R1Opnd:$rd), let isReMaterializable = 1 in { def LI16_NM : LoadImmediateNM<"li", GPRNM16R3Opnd, nimm7_nm, imm7M1To126>, LI16_Enc<0b11000>; +} +def : NMPat<(i32 imm32ZExt16:$imm), (ADDIU_NM ZERO_NM, imm:$imm)>; + +def : NMPat<(i32 imm32Neg12:$imm), (ADDIUNEG_NM ZERO_NM, imm:$imm)>; + +let isReMaterializable = 1 in { def LI48_NM : LoadAddressAbsNM<"li", GPRNM48Opnd, sym32_abs_nm, addrpcrel>, Op48_Imm_Enc<0b00000>; def ADDIUGP48_NM : LoadAddressGPRelNM<"addiu.b32", GPRNM48Opnd, sym32_gp_nm, diff --git a/llvm/test/CodeGen/Mips/nanomips/li.ll b/llvm/test/CodeGen/Mips/nanomips/li.ll index 7b91c9d45ce24..fb5eefae9f3af 100644 --- a/llvm/test/CodeGen/Mips/nanomips/li.ll +++ b/llvm/test/CodeGen/Mips/nanomips/li.ll @@ -4,7 +4,7 @@ define i32 @foo0() nounwind readnone { ; CHECK-LABEL: foo0 entry: ; CHECK: li $a0, 12345 -; CHECK: Li_NM +; CHECK: ADDIU_NM ret i32 12345 } @@ -12,7 +12,7 @@ define i32 @foo1() nounwind readnone { ; CHECK-LABEL: foo1 entry: ; CHECK: li $a0, -2147483648 -; CHECK: Li_NM +; CHECK: LI48_NM ret i32 -2147483648 } @@ -20,6 +20,22 @@ define i32 @foo2() nounwind readnone { ; CHECK-LABEL: foo2 entry: ; CHECK: li $a0, 2147483647 -; CHECK: Li_NM +; CHECK: LI48_NM ret i32 2147483647 } + +define i32 @foo4() nounwind readnone { +; CHECK-LABEL: foo4 +entry: +; CHECK: li $a0, -1 +; CHECK: LI16_NM + ret i32 -1 +} + +define i32 @foo5() nounwind readnone { +; CHECK-LABEL: foo5 +entry: +; CHECK: li $a0, -4095 +; CHECK: ADDIUNEG_NM + ret i32 -4095 +} From c45c55ef7940e261fce7f9b1ba3237affc7211b2 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 21 Feb 2023 20:32:59 +0530 Subject: [PATCH 111/123] Reorder 16-bit instruction patterns above 32-bit ones --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 95 ++++++++++++----------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 157b64948abc9..993826ecad87b 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1386,16 +1386,6 @@ class SaveRestore32_Enc isel> : _Pool_PP_SR { let Inst{2} = regs{0}; } -def SAVE_NM : SaveRestore<"save", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b00>; -def RESTORE_NM : SaveRestore<"restore", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b10>; -def RESTOREJRC_NM : SaveRestore<"restore.jrc", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b11>; - -def SAVE_NOREG_NM : MipsInstAlias<"save $adj", - (SAVE_NM uimm12s3_nm:$adj, 0)>; -def RESTORE_NOREG_NM : MipsInstAlias<"restore $adj", - (RESTORE_NM uimm12s3_nm:$adj, 0)>; -def RESTOREJRC_NOREG_NM : MipsInstAlias<"restore.jrc $adj", - (RESTOREJRC_NM uimm12s3_nm:$adj, 0)>; class SaveRestore16_Enc isel> : _Pool_P16_SR { bits<8> adj; @@ -1412,6 +1402,17 @@ def SAVE16_NOREG_NM : MipsInstAlias<"save $adj", def RESTOREJRC16_NOREG_NM : MipsInstAlias<"restore.jrc $adj", (RESTOREJRC16_NM uimm8s4_nm:$adj, 0)>; +def SAVE_NM : SaveRestore<"save", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b00>; +def RESTORE_NM : SaveRestore<"restore", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b10>; +def RESTOREJRC_NM : SaveRestore<"restore.jrc", uimm12s3_nm, nmreglist>, SaveRestore32_Enc<0b11>; + +def SAVE_NOREG_NM : MipsInstAlias<"save $adj", + (SAVE_NM uimm12s3_nm:$adj, 0)>; +def RESTORE_NOREG_NM : MipsInstAlias<"restore $adj", + (RESTORE_NM uimm12s3_nm:$adj, 0)>; +def RESTOREJRC_NOREG_NM : MipsInstAlias<"restore.jrc $adj", + (RESTOREJRC_NM uimm12s3_nm:$adj, 0)>; + class LoadMultipleNM : InstNM<(outs GPRNM32Opnd:$rt), (ins mem_nms9:$addr, uimm3plus1_nm:$count), @@ -1518,6 +1519,31 @@ class LoadImmediateNM, + ArithLogicR16_Enc<0b00>; +def XOR16_NM : ArithLogicR16_Desc<"xor", GPRNM16R3Opnd, xor>, + ArithLogicR16_Enc<0b01>; +def AND16_NM : ArithLogicR16_Desc<"and", GPRNM16R3Opnd, and>, + ArithLogicR16_Enc<0b10>; +def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM16R3Opnd, or>, + ArithLogicR16_Enc<0b11>; +} + +class ANDI16_Enc isel> : _Pool_P16 +{ + bits<3> rt; + bits<3> rs; + bits<4> imm; + let Inst{9...7} = rt; + let Inst{6...4} = rs; + let Inst{3...0} = imm; +} + +def ANDI16_NM : ArithLogicINM<"andi", uimm4mask_nm, GPRNM16R3Opnd, + imm4Mask, and>, ANDI16_Enc<0b11100>; + // _POOL32A0_0 pool of instructions. def SLLV_NM : ArithLogicR32_Desc<"sllv", GPRNM32Opnd, shl>, ArithLogicR32_Enc<0b000010>; @@ -1566,6 +1592,9 @@ def MODU_NM : DivMod<"modu", urem>, def SOV_NM : ArithLogicR32_Desc<"sov", GPRNM32Opnd>, ArithLogicR32_Enc<0b111110>; +def NOT_NM : MipsInstAlias<"not $rt, $rs", + (NOR_NM GPRNM32Opnd:$rt, GPRNM32Opnd:$rs, ZERO_NM)>; + // 16-bit register operations let FastISelShouldIgnore = 1, isCommutable=1 in { def SUBu16_NM : AddSubR16_Desc<"subu", GPRNM16R3Opnd, sub>, @@ -1595,14 +1624,14 @@ def SEQI_NM : CondLogicI32_Desc<"seqi", uimm12_nm, GPRNM32Opnd, imm32ZExt12, se CondLogicI32_Enc<0b0110>; // P.SHIFT pool of instructions -def SLL_NM : ShiftI_Desc<"sll", uimm5_nm, GPRNM32Opnd, imm32ZExt5, shl>, - ShiftI32_Enc<0b0000>; def SLL16_NM : ShiftI_Desc<"sll", uimm3shift_nm, GPRNM16R3Opnd, imm32ZExt3, shl>, ShiftI16_Enc<0b0>; -def SRL_NM : ShiftI_Desc<"srl", uimm5_nm, GPRNM32Opnd, imm32ZExt5, srl>, - ShiftI32_Enc<0b0010>; +def SLL_NM : ShiftI_Desc<"sll", uimm5_nm, GPRNM32Opnd, imm32ZExt5, shl>, + ShiftI32_Enc<0b0000>; def SRL16_NM : ShiftI_Desc<"srl", uimm3shift_nm, GPRNM16R3Opnd, imm32ZExt3, srl>, ShiftI16_Enc<0b1>; +def SRL_NM : ShiftI_Desc<"srl", uimm5_nm, GPRNM32Opnd, imm32ZExt5, srl>, + ShiftI32_Enc<0b0010>; def SRA_NM : ShiftI_Desc<"sra", uimm5_nm, GPRNM32Opnd, imm32ZExt5, sra>, ShiftI32_Enc<0b0100>; def ROTR_NM : ShiftI_Desc<"rotr", uimm5_nm, GPRNM32Opnd, imm32ZExt5, rotr>, @@ -1716,19 +1745,7 @@ def BYTEREVW_NM : ReverseNM<"byterevw", GPRNM32Opnd, bswap>; def TEQ_NM : Trap_Desc<"teq", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b0>; def TNE_NM : Trap_Desc<"tne", GPRNM32Opnd, uimm5_nm>, Trap_Enc<0b1>; -def NOT16_NM : ArithLogicR16U_Desc<"not", GPRNM16R3Opnd, not>, - ArithLogicR16_Enc<0b00>; -def NOT_NM : MipsInstAlias<"not $rt, $rs", - (NOR_NM GPRNM32Opnd:$rt, GPRNM32Opnd:$rs, ZERO_NM)>; -def XOR16_NM : ArithLogicR16_Desc<"xor", GPRNM16R3Opnd>, - ArithLogicR16_Enc<0b01>; -def AND16_NM : ArithLogicR16_Desc<"and", GPRNM16R3Opnd>, - ArithLogicR16_Enc<0b10>; -def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM16R3Opnd>, - ArithLogicR16_Enc<0b11>; - def JRC_NM : IndirectBranchNM<"jrc", GPRNM32Opnd>, IndirectBranch16_Enc<0>; -def JALRC16_NM : IndirectBranchNM<"jalrc", GPRNM32Opnd>, IndirectBranch16_Enc<1>; def MOVEBALC_NM : InstNM<(outs GPRNM1R1Opnd:$rd), (ins GPRNM4ZOpnd:$rt, calltarget21_nm:$addr), @@ -1768,19 +1785,6 @@ def ADDIUB32_NM : MipsInstAlias<"addiu.b32 $rt, $rs, $addr", def LA_NM : MipsInstAlias<"la $rt, $addr", (ADDIUPC48_NM GPRNM48Opnd:$rt, sym32_pc_nm:$addr)>; -class ANDI16_Enc isel> : _Pool_P16 -{ - bits<3> rt; - bits<3> rs; - bits<4> imm; - let Inst{9...7} = rt; - let Inst{6...4} = rs; - let Inst{3...0} = imm; -} - -def ANDI16_NM : ArithLogicINM<"andi", uimm4mask_nm, GPRNM16R3Opnd, - imm4Mask, add>, ANDI16_Enc<0b11100>; - // Arithmetic and logical instructions with 2 register operands and immediate. class LoadUpperINM, IndirectBranch16_Enc<1>; def JALRC_NM : IndirectCallNM<"jalrc", GPRNM32Opnd, GPRNM32Opnd>, IndirectCallNM_Enc<0b0000>; @@ -1959,12 +1964,6 @@ class BCBase let isCTI = 1; } -class BC32_Enc isel> : _Pool_P_BAL -{ - bits<26> addr; - let Inst{24...0} = addr{25...1}; -} - class BC16_Enc isel> : _Pool_P16 { bits<11> addr; @@ -1972,6 +1971,12 @@ class BC16_Enc isel> : _Pool_P16 let Inst{0} = addr{10}; } +class BC32_Enc isel> : _Pool_P_BAL +{ + bits<26> addr; + let Inst{24...0} = addr{25...1}; +} + class B14_Enc isel> : _Pool_P_BR12 { bits<5> rt; From 4c5d1829df7f24f393b2d429bba70ad31d1d9297 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 21 Feb 2023 21:26:33 +0530 Subject: [PATCH 112/123] Mark NOT16 as not commutable --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 993826ecad87b..cb3efd9b78084 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -1520,9 +1520,10 @@ class LoadImmediateNM, ArithLogicR16_Enc<0b00>; +let isCommutable=1 in { def XOR16_NM : ArithLogicR16_Desc<"xor", GPRNM16R3Opnd, xor>, ArithLogicR16_Enc<0b01>; def AND16_NM : ArithLogicR16_Desc<"and", GPRNM16R3Opnd, and>, @@ -1530,6 +1531,7 @@ def AND16_NM : ArithLogicR16_Desc<"and", GPRNM16R3Opnd, and>, def OR16_NM : ArithLogicR16_Desc<"or ", GPRNM16R3Opnd, or>, ArithLogicR16_Enc<0b11>; } +} class ANDI16_Enc isel> : _Pool_P16 { From 4a152533149dad83117c5c4eadd47f9e4b46c849 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 21 Feb 2023 22:25:58 +0530 Subject: [PATCH 113/123] Various codegen test updates after adding assembler support --- llvm/test/CodeGen/Mips/nanomips/addiu.ll | 24 +++++++++--------- llvm/test/CodeGen/Mips/nanomips/and.ll | 10 ++++---- llvm/test/CodeGen/Mips/nanomips/args.ll | 26 ++++++++++---------- llvm/test/CodeGen/Mips/nanomips/div.ll | 8 +++--- llvm/test/CodeGen/Mips/nanomips/jumptable.ll | 4 +-- llvm/test/CodeGen/Mips/nanomips/or.ll | 6 ++--- llvm/test/CodeGen/Mips/nanomips/setcc.ll | 18 +++++++------- llvm/test/CodeGen/Mips/nanomips/vararg.ll | 8 +++--- llvm/test/CodeGen/Mips/nanomips/xor.ll | 6 ++--- 9 files changed, 55 insertions(+), 55 deletions(-) diff --git a/llvm/test/CodeGen/Mips/nanomips/addiu.ll b/llvm/test/CodeGen/Mips/nanomips/addiu.ll index 1e57099200181..105bcdc2c8ec9 100644 --- a/llvm/test/CodeGen/Mips/nanomips/addiu.ll +++ b/llvm/test/CodeGen/Mips/nanomips/addiu.ll @@ -1,56 +1,56 @@ ; RUN: llc -mtriple=nanomips -asm-show-inst -verify-machineinstrs < %s | FileCheck %s define i32 @test_addiu0(i32 %a) { -; CHECK: addiu $a0, $a0, 1 +; CHECK: addiu $a0, $a0, 1 # Date: Thu, 23 Feb 2023 17:09:32 +0530 Subject: [PATCH 114/123] Fix GPRNM4Z register class - add missing zero --- llvm/lib/Target/Mips/MipsRegisterInfo.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td index d17976e09ae77..0735ab7aef77f 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -361,7 +361,7 @@ def GPRNM4 : // nanoMIPS "gpr4x4.zero" register encoding type. def GPRNM4Z : RegisterClass<"Mips", [i32], 32, - (add A0_NM, A1_NM, A2_NM, A3_NM, A4_NM, A5_NM, A6_NM, A7_NM, + (add A4_NM, A5_NM, A6_NM, ZERO_NM, A0_NM, A1_NM, A2_NM, A3_NM, S0_NM, S1_NM, S2_NM, S3_NM, S4_NM, S5_NM, S6_NM, S7_NM)>; // nanoMIPS non-zero gpr register encoding type. From 0a300580c0f1c82676e348b9ec55404cb73d63cd Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Fri, 24 Feb 2023 15:21:07 +0530 Subject: [PATCH 115/123] Uncomment tail-call match patterns (accidentally commented in 9216bd15c29f1a9e4e1deaddec212829a0209cb0) --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index cb3efd9b78084..379a639c18f3d 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -2146,10 +2146,10 @@ class TailCallRegBase : PseudoInstNM<(outs), (ins GPRNM32Opnd:$rs), } def TAILCALLREG_NM : TailCallRegBase; -//def : NMPat<(MipsTailCall (i32 tglobaladdr:$dst)), -// (TAILCALL_NM tglobaladdr:$dst)>; -//def : NMPat<(MipsTailCall (i32 texternalsym:$dst)), -// (TAILCALL_NM texternalsym:$dst)>; +def : NMPat<(MipsTailCall (i32 tglobaladdr:$dst)), + (TAILCALL_NM tglobaladdr:$dst)>; +def : NMPat<(MipsTailCall (i32 texternalsym:$dst)), + (TAILCALL_NM texternalsym:$dst)>; // '>-1' can be represented as '>=0'. def : NMPat<(brcond (i32 (setgt GPRNM32:$lhs, -1)), bb:$dst), From b313a746c8b14187842bde6d054c0884e38ef177 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 26 Feb 2023 10:48:21 +0530 Subject: [PATCH 116/123] Codegen test updates (merge with 4a152533149dad83117c5c4eadd47f9e4b46c849) --- llvm/test/CodeGen/Mips/nanomips/addiu.ll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/test/CodeGen/Mips/nanomips/addiu.ll b/llvm/test/CodeGen/Mips/nanomips/addiu.ll index 105bcdc2c8ec9..0c1780cbff66b 100644 --- a/llvm/test/CodeGen/Mips/nanomips/addiu.ll +++ b/llvm/test/CodeGen/Mips/nanomips/addiu.ll @@ -19,14 +19,14 @@ define i32 @test_addiu2(i32 %a) { } define i32 @test_addiu3(i32 %a) { -; CHECK: addiu $a0, $a0, -4096 # Date: Sun, 26 Feb 2023 10:49:54 +0530 Subject: [PATCH 117/123] Fix immediate value predicate for ADDIU[NEG] --- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 379a639c18f3d..fcc10e9020499 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -40,7 +40,9 @@ def imm32ZExt5 : IntImmLeaf(Imm.getZExtValue()); }]>; def imm32ZExt3 : IntImmLeaf 0 && Imm.getZExtValue() <= 8;}]>; def imm32SExt12 : IntImmLeaf(Imm.getSExtValue()); }]>; -def imm32Neg12 : IntImmLeaf(Imm.getSExtValue()) && Imm.getSExtValue() < 0; }]>; +def imm32Neg12 : IntImmLeaf(Imm.getSExtValue()) && + Imm.getSExtValue() < 0 && + Imm.getSExtValue() >= -4095; }]>; // True if (N + 1) fits in 12-bit field. def immZExt12Plus1 : PatLeaf<(imm), [{ return isUInt<13>(N->getZExtValue()) && isUInt<12>(N->getZExtValue() + 1); From 50ce854f7c2f54b9e135b0c9bdcd34a4a4fd3890 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 26 Feb 2023 16:24:15 +0530 Subject: [PATCH 118/123] Add 16-bit load & store word instructions to optimizer --- llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index b073ca54f2037..a8c9988dc5ce1 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -407,7 +407,8 @@ bool NMLoadStoreOpt::isValidLoadStore(MachineInstr &MI, bool IsLoad) { unsigned Opcode = MI.getOpcode(); if (IsLoad) { // TODO: Handle unaligned loads and stores. - if (Opcode == Mips::LW_NM || Opcode == Mips::LWs9_NM) { + if (Opcode == Mips::LW_NM || Opcode == Mips::LWs9_NM + || Opcode == Mips::LW16_NM || Opcode == Mips::LW4x4_NM) { // TODO: Rt and Rs can be equal, but only if that is the last load of // the sequence. Register Rt = MI.getOperand(0).getReg(); @@ -416,7 +417,8 @@ bool NMLoadStoreOpt::isValidLoadStore(MachineInstr &MI, bool IsLoad) { return true; } } else { - if (Opcode == Mips::SW_NM || Opcode == Mips::SWs9_NM) + if (Opcode == Mips::SW_NM || Opcode == Mips::SWs9_NM + || Opcode == Mips::SW16_NM || Opcode == Mips::SW4x4_NM) return true; } return false; From ba5ab89a3ec7a6052a60fec7ce456f37ea39b746 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 26 Feb 2023 16:29:18 +0530 Subject: [PATCH 119/123] Fix assembly parsing and disassembly for indexed memory operations --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 78 ++++++++++++++++++- .../Mips/Disassembler/MipsDisassembler.cpp | 21 +++++ .../Mips/MCTargetDesc/MipsInstPrinter.cpp | 26 ++++++- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 7 +- llvm/lib/Target/Mips/MipsInstrInfo.td | 8 -- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 44 +++++++---- 6 files changed, 151 insertions(+), 33 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 4832c215a1759..40d84911c5206 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -195,6 +195,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool ParseDirective(AsmToken DirectiveID) override; OperandMatchResultTy parseMemOperand(OperandVector &Operands); + OperandMatchResultTy parseMemNMRX(OperandVector &Operands); OperandMatchResultTy matchAnyRegisterNameWithoutDollar(OperandVector &Operands, StringRef Identifier, SMLoc S); @@ -1493,12 +1494,11 @@ class MipsOperand : public MCParsedAsmOperand { return false; } - bool isMemRx() const { + bool isMemNMRX() const { if (!isMem()) return false; if (!getMemBase()->isGPRAsmReg() - || (getConstantMemOff() < 0) - || (getConstantMemOff() > 31)) + || !MipsMCRegisterClasses[Mips::GPRNM32RegClassID].contains(getConstantMemOff())) return false; return true; } @@ -7034,6 +7034,78 @@ MipsAsmParser::parseMemOperand(OperandVector &Operands) { return MatchOperand_Success; } +// Parse register indexed memory operand - $rs($rt) +OperandMatchResultTy +MipsAsmParser::parseMemNMRX(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + LLVM_DEBUG(dbgs() << "parseMemRx\n"); + const MCExpr *IdVal = nullptr; + SMLoc S; + bool isParenExpr = false; + OperandMatchResultTy Res = MatchOperand_NoMatch; + + S = Parser.getTok().getLoc(); + + if (getLexer().getKind() == AsmToken::LParen) { + Parser.Lex(); + isParenExpr = true; + } + SmallVector, 1> Reg; + if ((Res = parseAnyRegister(Reg)) != MatchOperand_Success) + return Res; + else { + // Register encoded as immediate to fit struct MemOp + MipsOperand &RegOpnd = static_cast(*Reg[0]); + IdVal = MCConstantExpr::create(RegOpnd.getGPRNM32Reg(), getContext()); + } + + if (Parser.getTok().isNot(AsmToken::LParen)) { + if (Parser.getTok().is(AsmToken::EndOfStatement)) { + SMLoc E = + SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + + // Zero register assumed, add a memory operand with ZERO as its base. + // "Base" will be managed by k_Memory. + auto Base = MipsOperand::createGPRReg(0, "0", getContext().getRegisterInfo(), S, E, *this); + Operands.push_back( + MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); + return MatchOperand_Success; + } + else { + Error(Parser.getTok().getLoc(), "'(' expected"); + return MatchOperand_ParseFail; + } + } + else + Parser.Lex(); // Eat the '(' token. + + Res = parseAnyRegister(Operands); + if (Res != MatchOperand_Success) + return Res; + + if (Parser.getTok().isNot(AsmToken::RParen)) { + Error(Parser.getTok().getLoc(), "')' expected"); + return MatchOperand_ParseFail; + } + + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + + Parser.Lex(); // Eat the ')' token. + + if (!IdVal) + IdVal = MCConstantExpr::create(0, getContext()); + + // Replace the register operand with the memory operand. + std::unique_ptr op( + static_cast(Operands.back().release())); + // Remove the register from the operands. + // "op" will be managed by k_Memory. + Operands.pop_back(); + // Add the memory operand. + Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); + return MatchOperand_Success; +} + bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { MCAsmParser &Parser = getParser(); MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier()); diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 688223c2ad93f..94742e7776917 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -351,6 +351,11 @@ static DecodeStatus DecodeMemNM(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemNMRX(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemNM4x4(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1904,6 +1909,22 @@ static DecodeStatus DecodeMemNM(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeMemNMRX(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Offset = getReg(Decoder, Mips::GPRNM32RegClassID, + fieldFromInstruction(Insn, 0, 5)); + unsigned Base = getReg(Decoder, Mips::GPRNM32RegClassID, + fieldFromInstruction(Insn, 5, 5)); + + Inst.addOperand(MCOperand::createReg(Base)); + Inst.addOperand(MCOperand::createImm(Offset)); + + return MCDisassembler::Success; +} + + static DecodeStatus DecodeMemNM4x4(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp index 33fc90ea6ba5f..0d7308020b6e4 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp @@ -190,7 +190,31 @@ printMemOperand(const MCInst *MI, int opNum, raw_ostream &O) { break; } - printOperand(MI, opNum+1, O); + // Index register is encoded as immediate value + // in case of nanoMIPS indexed instructions + switch (MI->getOpcode()) { + case Mips::LWX_NM: + case Mips::LWXS_NM: + case Mips::LBX_NM: + case Mips::LBUX_NM: + case Mips::LHX_NM: + case Mips::LHUX_NM: + case Mips::LHXS_NM: + case Mips::LHUXS_NM: + case Mips::SWX_NM: + case Mips::SWXS_NM: + case Mips::SBX_NM: + case Mips::SHX_NM: + case Mips::SHXS_NM: + if (!MI->getOperand(opNum+1).isReg()) { + printRegName(O, MI->getOperand(opNum+1).getImm()); + break; + } + // Fall through + default: + printOperand(MI, opNum+1, O); + break; + } O << "("; printOperand(MI, opNum, O); O << ")"; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index b6cf58efe462b..3b5529295ce52 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -976,17 +976,16 @@ getMemEncodingNMRX(const MCInst &MI, unsigned OpNo, const MCSubtargetInfo &STI) const { // Register is encoded in bits 9-5, offset is encoded in bits 4-0. assert(MI.getOperand(OpNo).isReg()); - assert(MI.getOperand(OpNo+1).isReg()); - unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 5; - unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), + unsigned Reg = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + unsigned OffBits = Ctx.getRegisterInfo()->getEncodingValue(Reg); + return RegBits | OffBits; } - unsigned MipsMCCodeEmitter:: getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 3da36234ed5bd..b8d574c716786 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1126,14 +1126,6 @@ class MipsMemUimmAsmOperand : AsmOperandClass { "MemUImm" # Width # "Lsl" # Shift); } -def MipsMemRxAsmOperand : AsmOperandClass { - let Name = "MemRx"; - let SuperClasses = [MipsMemAsmOperand]; - let RenderMethod = "addMemOperands"; - let ParserMethod = "parseMemOperand"; - let PredicateMethod = "isMemRx"; -} - def MipsInvertedImmoperand : AsmOperandClass { let Name = "InvNum"; let RenderMethod = "addImmOperands"; diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index fcc10e9020499..4ef40d43d25fa 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -30,7 +30,11 @@ def imm32_NM : IntImmLeaf; def immFitsAddiu32 : IntImmLeaf= -4095) || (N > 4095 && N <= 65535); + return (N > 4095 && N <= 65535); +}]>; +def immFitsAddiuNeg : IntImmLeaf= -4095); }]>; def imm32ZExt12 : IntImmLeaf(Imm.getZExtValue()); }]>; def imm32ZExt12ANDI : @@ -399,9 +403,18 @@ def mem_nmpcrel : mem_generic { let ParserMatchClass = MipsMemSimmAsmOperand<9>; } +def NMMemRXAsmOperand : AsmOperandClass { + let Name = "NMMemRX"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addNMMemOperands"; + let ParserMethod = "parseMemNMRX"; + let PredicateMethod = "isMemNMRX"; +} + def mem_nmrx : mem_generic { let EncoderMethod = "getMemEncodingNMRX"; - let ParserMatchClass = MipsMemRxAsmOperand; + let DecoderMethod = "DecodeMemNMRX"; + let ParserMatchClass = NMMemRXAsmOperand; } foreach I = {4, 7, 10, 11, 14, 25} in @@ -1042,10 +1055,9 @@ class LSMem_U12_Enc isel> : _Pool_P_LS_U12 class LSMemX_Enc isel> : _Pool_PP_LSX { bits<5> rd; - bits<5> index; - bits<5> base; - let Inst{25...21} = base; - let Inst{20...16} = index; + bits<10> addr; + let Inst{25...21} = addr{9...5}; + let Inst{20...16} = addr{4...0}; let Inst{15...11} = rd; } @@ -1185,11 +1197,10 @@ class LoadMemoryX : - InstNM<(outs GPRNM32Opnd:$rd), (ins PtrRC:$base, PtrRC:$index), - !strconcat(opstr, "\t$rd, ${index}(${base})"), - [], + InstNM<(outs GPRNM32Opnd:$rd), (ins MO:$addr), + !strconcat(opstr, "\t$rd, $addr"), + [(set GPRNM32Opnd:$rd, (OpNode Addr:$addr))], itin> { - let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; let mayLoad = 1; string BaseOpcode = opstr; @@ -1199,11 +1210,10 @@ class StoreMemoryX : - InstNM<(outs), (ins GPRNM32Opnd:$rd, PtrRC:$base, PtrRC:$index), - !strconcat(opstr, "\t$rd, ${index}(${base})"), - [], + InstNM<(outs), (ins GPRNM32Opnd:$rd, MO:$addr), + !strconcat(opstr, "\t$rd, ${addr}"), + [(OpNode GPRNM32Opnd:$rd, Addr:$addr)], itin> { - let DecoderMethod = "DecodeMem"; let mayStore = 1; string BaseOpcode = opstr; } @@ -2391,12 +2401,12 @@ def : NMPat<(store GPRNM32:$rt, GPRNM32:$rs), // Any-extending loads def : NMPat<(i32 (extloadi8 addruimm12:$addr)), (LBU_NM addruimm12:$addr)>; def : NMPat<(i32 (extloadi8 addrsimm9:$addr)), (LBUs9_NM addrsimm9:$addr)>; -def : NMPat<(i32 (extloadi8 addrindexed:$addr)), (LBUX_NM addrindexed:$addr, 0)>; +def : NMPat<(i32 (extloadi8 addrindexed:$addr)), (LBUX_NM addrindexed:$addr)>; def : NMPat<(i32 (extloadi16 addruimm12:$addr)), (LHU_NM addruimm12:$addr)>; def : NMPat<(i32 (extloadi16 addrsimm9:$addr)), (LHUs9_NM addrsimm9:$addr)>; def : NMPat<(i32 (extloadi16 addrindexedlsl1:$addr)), - (LHUXS_NM addrindexedlsl1:$addr, 0)>; -def : NMPat<(i32 (extloadi16 addrindexed:$addr)), (LHUX_NM addrindexed:$addr, 0)>; + (LHUXS_NM addrindexedlsl1:$addr)>; +def : NMPat<(i32 (extloadi16 addrindexed:$addr)), (LHUX_NM addrindexed:$addr)>; // Catching out-of-range immediate unaligned loads/stores. def : NMPat<(i32 (NMUnalignedLW GPRNM32:$rs, GPRNM32:$src)), From 72b884a425b01b0ff2aab1f3ac2f50017f173afd Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 26 Feb 2023 17:30:15 +0530 Subject: [PATCH 120/123] Add UALW/UASW as independent instructions instead of aliases --- llvm/lib/Target/Mips/MipsScheduleGeneric.td | 4 ++-- llvm/lib/Target/Mips/NanoMipsInstrInfo.td | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td index 50b4632c14db7..bb1c212e128e1 100644 --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -731,7 +731,7 @@ def : InstRW<[GenericWriteLoad], (instrs LW_NM, LWGP_NM, LWs9_NM, LHX_NM, LHXS_NM, LBUX_NM, LBX_NM, RESTOREJRC16_NM, RESTOREJRC_NM, RESTORE_NM, SAVE_NM, SAVE16_NM, - UALH_NM, LWM_NM, UALWM_NM, + UALH_NM, LWM_NM, UALWM_NM, UALW_NM, LWPC_NM, LW16_NM, LH16_NM, LHU16_NM, LB16_NM, LBU16_NM, LBGP_NM, LBUGP_NM, LHGP_NM, LHUGP_NM, LW4x4_NM)>; @@ -741,7 +741,7 @@ def: InstRW<[GenericWriteStore], (instrs SW_NM, SWs9_NM, SW16_NM, SH16_NM, SB_NM, SBs9_NM, SB16_NM, LWGP16_NM, SWGP16_NM, LWSP16_NM, SWSP16_NM, SW4x4_NM, SWX_NM, SWXS_NM, SHX_NM, SHXS_NM, SBX_NM, - UASH_NM, SWM_NM, UASWM_NM, SWPC_NM)>; + UASH_NM, SWM_NM, UASWM_NM, UASW_NM, SWPC_NM)>; // microMIPS32r6 // ============= diff --git a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td index 4ef40d43d25fa..791f1472fe38f 100644 --- a/llvm/lib/Target/Mips/NanoMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/NanoMipsInstrInfo.td @@ -2318,10 +2318,8 @@ def UALWM_NM : LoadMultipleNM<"ualwm">, LSMem_S9_Mult_Enc<0b0101>; def SWM_NM : StoreMultipleNM<"swm">, LSMem_S9_Mult_Enc<0b1100>; def UASWM_NM : StoreMultipleNM<"uaswm">, LSMem_S9_Mult_Enc<0b1101>; -def UALW_NM : MipsInstAlias<"ualw $rt, $addr", - (UALWM_NM GPRNM32Opnd:$rt, mem_nms9:$addr, 1)>; -def UASW_NM : MipsInstAlias<"uasw $rt, $addr", - (UASWM_NM GPRNM32Opnd:$rt, mem_nms9:$addr, 1)>; +def UALW_NM : UnalignedLoad<"ualw", NMUnalignedLW>, LSMem_S9_Enc<0b101, 0b0010>; +def UASW_NM : UnalignedStore<"uasw", NMUnalignedSW>, LSMem_S9_Enc<0b101, 0b0011>; //def CACHE_NM : LSMem_S9_Enc<0b001, 0b0111>; @@ -2410,9 +2408,9 @@ def : NMPat<(i32 (extloadi16 addrindexed:$addr)), (LHUX_NM addrindexed:$addr)>; // Catching out-of-range immediate unaligned loads/stores. def : NMPat<(i32 (NMUnalignedLW GPRNM32:$rs, GPRNM32:$src)), - (UALWM_NM GPRNM32:$rs, GPRNM32:$src, 1)>; + (UALW_NM GPRNM32:$rs, 0, GPRNM32:$src)>; def : NMPat<(NMUnalignedSW GPRNM32:$rt, GPRNM32:$rs), - (UASWM_NM GPRNM32:$rt, GPRNM32:$rs, 0, 1)>; + (UASW_NM GPRNM32:$rt, GPRNM32:$rs, 0)>; def : NMPat<(i32 (NMUnalignedLH GPRNM32:$rs, GPRNM32:$src)), (UALH_NM GPRNM32:$rs, 0, GPRNM32:$src)>; def : NMPat<(NMUnalignedSH GPRNM32:$rt, GPRNM32:$rs), From a4d6697635254deb85ff842fd9fb370fdb23308e Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 26 Feb 2023 17:31:23 +0530 Subject: [PATCH 121/123] Codegen test updates (unaligned-memops, storezero) --- llvm/test/CodeGen/Mips/nanomips/storezero.ll | 2 +- .../CodeGen/Mips/nanomips/unaligned-memops.ll | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/llvm/test/CodeGen/Mips/nanomips/storezero.ll b/llvm/test/CodeGen/Mips/nanomips/storezero.ll index 774c9a7b8d16c..536cf476aecff 100644 --- a/llvm/test/CodeGen/Mips/nanomips/storezero.ll +++ b/llvm/test/CodeGen/Mips/nanomips/storezero.ll @@ -83,7 +83,7 @@ define void @zerointunaligned2(i32* %num) { define void @zerointunaligned3(i32* %num) { %arrayidx = getelementptr inbounds i32, i32* %num, i32 10000 -; CHECK: uasw $zero, 0($a0) +; CHECK: uasw $zero, 0($a3) store i32 0, i32* %arrayidx, align 2 ret void } diff --git a/llvm/test/CodeGen/Mips/nanomips/unaligned-memops.ll b/llvm/test/CodeGen/Mips/nanomips/unaligned-memops.ll index 21acdd33a4923..2e21893bedfaa 100644 --- a/llvm/test/CodeGen/Mips/nanomips/unaligned-memops.ll +++ b/llvm/test/CodeGen/Mips/nanomips/unaligned-memops.ll @@ -8,9 +8,9 @@ define i32 @ualw_1(i32* %a) { } define i32 @ualw_2(i32* %a) { -; CHECK: addiu $a0, $a0, 256 -; CHECK: ADDiu_NM -; CHECK: ualw $a0, 0($a0) +; CHECK: addiu $a3, $a0, 256 +; CHECK: ADDIU_NM +; CHECK: ualw $a0, 0($a3) ; CHECK: UALW_NM %a1 = getelementptr inbounds i32, i32* %a, i64 64 %1 = load i32, i32* %a1, align 1 @@ -27,7 +27,7 @@ define i32 @ualw_3(i32* %a) { define i32 @ualw_4(i32* %a) { ; CHECK: addiu $a0, $a0, -260 -; CHECK: ADDiu_NM +; CHECK: ADDIUNEG_NM ; CHECK: ualw $a0, 0($a0) ; CHECK: UALW_NM %a1 = getelementptr inbounds i32, i32* %a, i64 -65 @@ -51,9 +51,9 @@ define void @uasw_1(i32* %a) { } define void @uasw_2(i32* %a) { -; CHECK: addiu $a0, $a0, 256 -; CHECK: ADDiu_NM -; CHECK: uasw $a1, 0($a0) +; CHECK: addiu $a3, $a0, 256 +; CHECK: ADDIU_NM +; CHECK: uasw $a0, 0($a3) ; CHECK: UASW_NM %a1 = getelementptr inbounds i32, i32* %a, i64 64 store i32 1, i32* %a1, align 1 @@ -70,7 +70,7 @@ define void @uasw_3(i32* %a) { define void @uasw_4(i32* %a) { ; CHECK: addiu $a0, $a0, -260 -; CHECK: ADDiu_NM +; CHECK: ADDIUNEG_NM ; CHECK: uasw $a1, 0($a0) ; CHECK: UASW_NM %a1 = getelementptr inbounds i32, i32* %a, i64 -65 From 4807db25c0e3e391d029370d8533d161632c8f13 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 26 Feb 2023 17:43:01 +0530 Subject: [PATCH 122/123] Change ADDIU_NM to ADDIUNEG_NM for SP adjustment --- llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index a8c9988dc5ce1..d3bc47429fa7e 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -383,7 +383,7 @@ bool NMLoadStoreOpt::generateSaveOrRestore(MachineBasicBlock &MBB, // In case of save, the offset is subtracted from SP. if (!IsRestore) NewStackOffset = -NewStackOffset; - BuildMI(MBB, InsertBefore, DL, TII->get(Mips::ADDIU_NM), Mips::SP_NM) + BuildMI(MBB, InsertBefore, DL, TII->get(Mips::ADDIUNEG_NM), Mips::SP_NM) .addReg(Mips::SP_NM) .addImm(NewStackOffset); } @@ -577,6 +577,7 @@ static bool isValidUse(MachineInstr *MI, Register Reg) { case Mips::LW_NM: case Mips::LWs9_NM: case Mips::ADDIU_NM: + case Mips::ADDIUNEG_NM: case Mips::LH16_NM: case Mips::LHU16_NM: case Mips::SH16_NM: From 872420c750731540569bacb1c2cf968eb0602093 Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Mon, 20 Mar 2023 22:16:13 +0530 Subject: [PATCH 123/123] Add assembler encoding tests (WIP) --- llvm/test/MC/Mips/nanomips/valid.s | 867 +++++++++++++++++++++++++++++ 1 file changed, 867 insertions(+) create mode 100644 llvm/test/MC/Mips/nanomips/valid.s diff --git a/llvm/test/MC/Mips/nanomips/valid.s b/llvm/test/MC/Mips/nanomips/valid.s new file mode 100644 index 0000000000000..423e1f3246a4e --- /dev/null +++ b/llvm/test/MC/Mips/nanomips/valid.s @@ -0,0 +1,867 @@ +# Instructions that are valid +# +# Branches have some unusual encoding rules in nanoMIPS so we need to test: +# rs == 0 +# rs != 0 +# rt == 0 +# rt != 0 +# rs < rt +# rs == rt +# rs > rt +# appropriately for each branch instruction +# +# RUN: llvm-mc %s -triple=nanomips-elf -show-encoding -show-inst 2> %t0 | FileCheck %s + # CHECK: .text + .set noat +# .linkrelax + # reg3-reg3 arithmetic, 16-bit + addu $a1, $s2, $a3 # CHECK: addu $a1, $s2, $a3 # encoding: [0xaa,0xb3] + # CHECK-NEXT: #