From: Jack Carter Date: Tue, 13 Aug 2013 20:54:07 +0000 (+0000) Subject: [Mips][msa] Added initial MSA support. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=3f70e908c3d9de7acea462719ebf36dca1560f9c [Mips][msa] Added initial MSA support. * msa SubtargetFeature * registers * ld.[bhwd], and st.[bhwd] instructions Does not correctly prohibit use of both 32-bit FPU registers and MSA together. Patch by Daniel Sanders git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188313 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index 2595e41a877..b8e3f39256d 100644 --- a/lib/Target/Mips/Mips.td +++ b/lib/Target/Mips/Mips.td @@ -78,6 +78,8 @@ def FeatureDSP : SubtargetFeature<"dsp", "HasDSP", "true", "Mips DSP ASE">; def FeatureDSPR2 : SubtargetFeature<"dspr2", "HasDSPR2", "true", "Mips DSP-R2 ASE", [FeatureDSP]>; +def FeatureMSA : SubtargetFeature<"msa", "HasMSA", "true", "Mips MSA ASE">; + def FeatureMicroMips : SubtargetFeature<"micromips", "InMicroMipsMode", "true", "microMips mode">; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 3806b33adb6..abc2d16b077 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -1420,6 +1420,10 @@ include "Mips16InstrInfo.td" include "MipsDSPInstrFormats.td" include "MipsDSPInstrInfo.td" +// MSA +include "MipsMSAInstrFormats.td" +include "MipsMSAInstrInfo.td" + // Micromips include "MicroMipsInstrFormats.td" include "MicroMipsInstrInfo.td" diff --git a/lib/Target/Mips/MipsMSAInstrFormats.td b/lib/Target/Mips/MipsMSAInstrFormats.td new file mode 100644 index 00000000000..7cc1a88bd67 --- /dev/null +++ b/lib/Target/Mips/MipsMSAInstrFormats.td @@ -0,0 +1,34 @@ +//===- MipsMSAInstrFormats.td - Mips Instruction Formats ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +def HasMSA : Predicate<"Subtarget.hasMSA()">, + AssemblerPredicate<"FeatureMSA">; + +class MSAInst : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther> { + let Predicates = [HasMSA]; + let Inst{31-26} = 0b011110; +} + +class PseudoMSA pattern, + InstrItinClass itin = IIPseudo>: + MipsPseudo { + let Predicates = [HasMSA]; +} + +class MSA_3R_FMT major, bits<2> df, bits<6> minor>: MSAInst { + let Inst{25-23} = major; + let Inst{22-21} = df; + let Inst{5-0} = minor; +} + +class MSA_I5_FMT major, bits<2> df, bits<6> minor>: MSAInst { + let Inst{25-23} = major; + let Inst{22-21} = df; + let Inst{5-0} = minor; +} diff --git a/lib/Target/Mips/MipsMSAInstrInfo.td b/lib/Target/Mips/MipsMSAInstrInfo.td new file mode 100644 index 00000000000..24482c07524 --- /dev/null +++ b/lib/Target/Mips/MipsMSAInstrInfo.td @@ -0,0 +1,69 @@ +//===- MipsMSAInstrInfo.td - MSA ASE instructions -*- tablegen ------------*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes Mips MSA ASE instructions. +// +//===----------------------------------------------------------------------===// + +// Instruction encoding. +class LD_B_ENC : MSA_I5_FMT<0b110, 0b00, 0b000111>; +class LD_H_ENC : MSA_I5_FMT<0b110, 0b01, 0b000111>; +class LD_W_ENC : MSA_I5_FMT<0b110, 0b10, 0b000111>; +class LD_D_ENC : MSA_I5_FMT<0b110, 0b11, 0b000111>; +class ST_B_ENC : MSA_I5_FMT<0b111, 0b00, 0b000111>; +class ST_H_ENC : MSA_I5_FMT<0b111, 0b01, 0b000111>; +class ST_W_ENC : MSA_I5_FMT<0b111, 0b10, 0b000111>; +class ST_D_ENC : MSA_I5_FMT<0b111, 0b11, 0b000111>; + +// Instruction desc. +class LD_DESC_BASE { + dag OutOperandList = (outs RCWD:$wd); + dag InOperandList = (ins MemOpnd:$addr); + string AsmString = !strconcat(instr_asm, "\t$wd, $addr"); + list Pattern = [(set RCWD:$wd, (TyNode (OpNode Addr:$addr)))]; + InstrItinClass Itinerary = itin; +} + +class ST_DESC_BASE { + dag OutOperandList = (outs); + dag InOperandList = (ins RCWD:$wd, MemOpnd:$addr); + string AsmString = !strconcat(instr_asm, "\t$wd, $addr"); + list Pattern = [(OpNode (TyNode RCWD:$wd), Addr:$addr)]; + InstrItinClass Itinerary = itin; +} + +// Load/Store +class LD_B_DESC : LD_DESC_BASE<"ld.b", load, v16i8, NoItinerary, MSA128>; +class LD_H_DESC : LD_DESC_BASE<"ld.h", load, v8i16, NoItinerary, MSA128>; +class LD_W_DESC : LD_DESC_BASE<"ld.w", load, v4i32, NoItinerary, MSA128>; +class LD_D_DESC : LD_DESC_BASE<"ld.d", load, v2i64, NoItinerary, MSA128>; +class ST_B_DESC : ST_DESC_BASE<"st.b", store, v16i8, NoItinerary, MSA128>; +class ST_H_DESC : ST_DESC_BASE<"st.h", store, v8i16, NoItinerary, MSA128>; +class ST_W_DESC : ST_DESC_BASE<"st.w", store, v4i32, NoItinerary, MSA128>; +class ST_D_DESC : ST_DESC_BASE<"st.d", store, v2i64, NoItinerary, MSA128>; + +// Instruction defs. +def LD_B: LD_B_ENC, LD_B_DESC, Requires<[HasMSA]>; +def LD_H: LD_H_ENC, LD_H_DESC, Requires<[HasMSA]>; +def LD_W: LD_W_ENC, LD_W_DESC, Requires<[HasMSA]>; +def LD_D: LD_D_ENC, LD_D_DESC, Requires<[HasMSA]>; + +def ST_B: ST_B_ENC, ST_B_DESC, Requires<[HasMSA]>; +def ST_H: ST_H_ENC, ST_H_DESC, Requires<[HasMSA]>; +def ST_W: ST_W_ENC, ST_W_DESC, Requires<[HasMSA]>; +def ST_D: ST_D_ENC, ST_D_DESC, Requires<[HasMSA]>; + +// Patterns. +class MSAPat : + Pat, Requires<[pred]>; + diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index aa5d39c6a35..adc0a7972d7 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -14,6 +14,7 @@ let Namespace = "Mips" in { def sub_fpeven : SubRegIndex<32>; def sub_fpodd : SubRegIndex<32, 32>; def sub_32 : SubRegIndex<32>; +def sub_64 : SubRegIndex<64>; def sub_lo : SubRegIndex<32>; def sub_hi : SubRegIndex<32, 32>; def sub_dsp16_19 : SubRegIndex<4, 16>; @@ -63,6 +64,12 @@ class AFPR64 Enc, string n, list subregs> let SubRegIndices = [sub_32]; } +// Mips 128-bit (aliased) MSA Registers +class AFPR128 Enc, string n, list subregs> + : MipsRegWithSubRegs { + let SubRegIndices = [sub_64]; +} + // Accumulator Registers class ACCReg Enc, string n, list subregs> : MipsRegWithSubRegs { @@ -162,6 +169,41 @@ let Namespace = "Mips" in { def D#I#_64 : AFPR64("F"#I)]>, DwarfRegNum<[!add(I, 32)]>; + /// Mips MSA registers + /// MSA and FPU cannot both be present unless the FPU has 64-bit registers + def W0 : AFPR128<0, "w0", [D0_64]>, DwarfRegNum<[32]>; + def W1 : AFPR128<1, "w1", [D1_64]>, DwarfRegNum<[33]>; + def W2 : AFPR128<2, "w2", [D2_64]>, DwarfRegNum<[34]>; + def W3 : AFPR128<3, "w3", [D3_64]>, DwarfRegNum<[35]>; + def W4 : AFPR128<4, "w4", [D4_64]>, DwarfRegNum<[36]>; + def W5 : AFPR128<5, "w5", [D5_64]>, DwarfRegNum<[37]>; + def W6 : AFPR128<6, "w6", [D6_64]>, DwarfRegNum<[38]>; + def W7 : AFPR128<7, "w7", [D7_64]>, DwarfRegNum<[39]>; + def W8 : AFPR128<8, "w8", [D8_64]>, DwarfRegNum<[40]>; + def W9 : AFPR128<9, "w9", [D9_64]>, DwarfRegNum<[41]>; + def W10 : AFPR128<10, "w10", [D10_64]>, DwarfRegNum<[42]>; + def W11 : AFPR128<11, "w11", [D11_64]>, DwarfRegNum<[43]>; + def W12 : AFPR128<12, "w12", [D12_64]>, DwarfRegNum<[44]>; + def W13 : AFPR128<13, "w13", [D13_64]>, DwarfRegNum<[45]>; + def W14 : AFPR128<14, "w14", [D14_64]>, DwarfRegNum<[46]>; + def W15 : AFPR128<15, "w15", [D15_64]>, DwarfRegNum<[47]>; + def W16 : AFPR128<16, "w16", [D16_64]>, DwarfRegNum<[48]>; + def W17 : AFPR128<17, "w17", [D17_64]>, DwarfRegNum<[49]>; + def W18 : AFPR128<18, "w18", [D18_64]>, DwarfRegNum<[50]>; + def W19 : AFPR128<19, "w19", [D19_64]>, DwarfRegNum<[51]>; + def W20 : AFPR128<20, "w20", [D20_64]>, DwarfRegNum<[52]>; + def W21 : AFPR128<21, "w21", [D21_64]>, DwarfRegNum<[53]>; + def W22 : AFPR128<22, "w22", [D22_64]>, DwarfRegNum<[54]>; + def W23 : AFPR128<23, "w23", [D23_64]>, DwarfRegNum<[55]>; + def W24 : AFPR128<24, "w24", [D24_64]>, DwarfRegNum<[56]>; + def W25 : AFPR128<25, "w25", [D25_64]>, DwarfRegNum<[57]>; + def W26 : AFPR128<26, "w26", [D26_64]>, DwarfRegNum<[58]>; + def W27 : AFPR128<27, "w27", [D27_64]>, DwarfRegNum<[59]>; + def W28 : AFPR128<28, "w28", [D28_64]>, DwarfRegNum<[60]>; + def W29 : AFPR128<29, "w29", [D29_64]>, DwarfRegNum<[61]>; + def W30 : AFPR128<30, "w30", [D30_64]>, DwarfRegNum<[62]>; + def W31 : AFPR128<31, "w31", [D31_64]>, DwarfRegNum<[63]>; + // Hi/Lo registers def HI : Register<"ac0">, DwarfRegNum<[64]>; def HI1 : Register<"ac1">, DwarfRegNum<[176]>; @@ -302,6 +344,9 @@ def CCR : RegisterClass<"Mips", [i32], 32, (sequence "FCR%u", 0, 31)>, def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>, Unallocatable; +def MSA128: RegisterClass<"Mips", [v16i8, v8i16, v4i32, v2i64], 128, + (sequence "W%u", 0, 31)>; + // Hi/Lo Registers def LORegs : RegisterClass<"Mips", [i32], 32, (add LO)>; def HIRegs : RegisterClass<"Mips", [i32], 32, (add HI)>; diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index a0aacb57e47..979cfcb31da 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -77,6 +77,23 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) if (Subtarget->hasDSPR2()) setOperationAction(ISD::MUL, MVT::v2i16, Legal); + if (Subtarget->hasMSA()) { + MVT::SimpleValueType VecTys[4] = {MVT::v16i8, MVT::v8i16, + MVT::v4i32, MVT::v2i64}; + + for (unsigned i = 0; i < array_lengthof(VecTys); ++i) { + addRegisterClass(VecTys[i], &Mips::MSA128RegClass); + + // Expand all builtin opcodes. + for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) + setOperationAction(Opc, VecTys[i], Expand); + + setOperationAction(ISD::LOAD, VecTys[i], Legal); + setOperationAction(ISD::STORE, VecTys[i], Legal); + setOperationAction(ISD::BITCAST, VecTys[i], Legal); + } + } + if (!TM.Options.UseSoftFloat) { addRegisterClass(MVT::f32, &Mips::FGR32RegClass); diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index 541e2ca4da9..e2e7e08d620 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -65,7 +65,7 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, HasBitCount(false), HasFPIdx(false), InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), - AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), + AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasMSA(false), RM(_RM), OverrideMode(NoOverride), TM(_TM) { std::string CPUName = CPU; diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index bfb13bb4802..21d6938adac 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -113,6 +113,9 @@ protected: // compiled as Mips32 bool Os16; + // HasMSA -- supports MSA ASE. + bool HasMSA; + InstrItineraryData InstrItins; // The instance to the register info section object @@ -182,6 +185,7 @@ public: bool inMicroMipsMode() const { return InMicroMipsMode; } bool hasDSP() const { return HasDSP; } bool hasDSPR2() const { return HasDSPR2; } + bool hasMSA() const { return HasMSA; } bool isLinux() const { return IsLinux; } bool useSmallSection() const { return UseSmallSection; }