From: Daniel Sanders Date: Wed, 28 Aug 2013 10:26:24 +0000 (+0000) Subject: [mips][msa] Added cfcmsa, and ctcmsa X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=a6c3a4ee76ef8464d3c83472e15af521ade7eeb4;p=oota-llvm.git [mips][msa] Added cfcmsa, and ctcmsa The MSA control registers have been added as reserved registers, and are only used via ISD::Copy(To|From)Reg. The intrinsics are lowered into these nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189468 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/IntrinsicsMips.td b/include/llvm/IR/IntrinsicsMips.td index 55d4c4d1477..0bcbbd837f6 100644 --- a/include/llvm/IR/IntrinsicsMips.td +++ b/include/llvm/IR/IntrinsicsMips.td @@ -679,6 +679,9 @@ def int_mips_ceqi_w : GCCBuiltin<"__builtin_msa_ceqi_w">, def int_mips_ceqi_d : GCCBuiltin<"__builtin_msa_ceqi_d">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; +def int_mips_cfcmsa : GCCBuiltin<"__builtin_msa_cfcmsa">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + def int_mips_cle_s_b : GCCBuiltin<"__builtin_msa_cle_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_mips_cle_s_h : GCCBuiltin<"__builtin_msa_cle_s_h">, @@ -765,6 +768,9 @@ def int_mips_copy_u_h : GCCBuiltin<"__builtin_msa_copy_u_h">, def int_mips_copy_u_w : GCCBuiltin<"__builtin_msa_copy_u_w">, Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty], []>; +def int_mips_ctcmsa : GCCBuiltin<"__builtin_msa_ctcmsa">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>; + def int_mips_div_s_b : GCCBuiltin<"__builtin_msa_div_s_b">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_mips_div_s_h : GCCBuiltin<"__builtin_msa_div_s_h">, diff --git a/lib/Target/Mips/MipsMSAInstrFormats.td b/lib/Target/Mips/MipsMSAInstrFormats.td index 35082c2912f..f337f9d8fff 100644 --- a/lib/Target/Mips/MipsMSAInstrFormats.td +++ b/lib/Target/Mips/MipsMSAInstrFormats.td @@ -69,6 +69,11 @@ class MSA_3RF_FMT major, bits<1> df, bits<6> minor>: MSAInst { let Inst{5-0} = minor; } +class MSA_ELM_FMT major, bits<6> minor>: MSAInst { + let Inst{25-16} = major; + let Inst{5-0} = minor; +} + class MSA_ELM_B_FMT major, bits<6> minor>: MSAInst { let Inst{25-22} = major; let Inst{21-20} = 0b00; diff --git a/lib/Target/Mips/MipsMSAInstrInfo.td b/lib/Target/Mips/MipsMSAInstrInfo.td index e7688ca2ddc..e53b29ec657 100644 --- a/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/lib/Target/Mips/MipsMSAInstrInfo.td @@ -171,6 +171,8 @@ class CEQI_H_ENC : MSA_I5_FMT<0b000, 0b01, 0b000111>; class CEQI_W_ENC : MSA_I5_FMT<0b000, 0b10, 0b000111>; class CEQI_D_ENC : MSA_I5_FMT<0b000, 0b11, 0b000111>; +class CFCMSA_ENC : MSA_ELM_FMT<0b0001111110, 0b011001>; + class CLE_S_B_ENC : MSA_3R_FMT<0b100, 0b00, 0b001111>; class CLE_S_H_ENC : MSA_3R_FMT<0b100, 0b01, 0b001111>; class CLE_S_W_ENC : MSA_3R_FMT<0b100, 0b10, 0b001111>; @@ -219,6 +221,8 @@ class COPY_U_B_ENC : MSA_ELM_B_FMT<0b0011, 0b011001>; class COPY_U_H_ENC : MSA_ELM_H_FMT<0b0011, 0b011001>; class COPY_U_W_ENC : MSA_ELM_W_FMT<0b0011, 0b011001>; +class CTCMSA_ENC : MSA_ELM_FMT<0b0000111110, 0b011001>; + class DIV_S_B_ENC : MSA_3R_FMT<0b100, 0b00, 0b010010>; class DIV_S_H_ENC : MSA_3R_FMT<0b100, 0b01, 0b010010>; class DIV_S_W_ENC : MSA_3R_FMT<0b100, 0b10, 0b010010>; @@ -1155,6 +1159,14 @@ class CEQI_W_DESC : MSA_SI5_DESC_BASE<"ceqi.w", int_mips_ceqi_w, NoItinerary, class CEQI_D_DESC : MSA_SI5_DESC_BASE<"ceqi.d", int_mips_ceqi_d, NoItinerary, MSA128D, MSA128D>; +class CFCMSA_DESC { + dag OutOperandList = (outs GPR32:$rd); + dag InOperandList = (ins MSACtrl:$cs); + string AsmString = "cfcmsa\t$rd, $cs"; + InstrItinClass Itinerary = NoItinerary; + bit hasSideEffects = 1; +} + class CLE_S_B_DESC : MSA_3R_DESC_BASE<"cle_s.b", int_mips_cle_s_b, NoItinerary, MSA128B, MSA128B>; class CLE_S_H_DESC : MSA_3R_DESC_BASE<"cle_s.h", int_mips_cle_s_h, NoItinerary, @@ -1241,6 +1253,14 @@ class COPY_U_H_DESC : MSA_COPY_DESC_BASE<"copy_u.h", int_mips_copy_u_h, class COPY_U_W_DESC : MSA_COPY_DESC_BASE<"copy_u.w", int_mips_copy_u_w, NoItinerary, GPR32, MSA128W>; +class CTCMSA_DESC { + dag OutOperandList = (outs); + dag InOperandList = (ins MSACtrl:$cd, GPR32:$rs); + string AsmString = "ctcmsa\t$cd, $rs"; + InstrItinClass Itinerary = NoItinerary; + bit hasSideEffects = 1; +} + class DIV_S_B_DESC : MSA_3R_DESC_BASE<"div_s.b", int_mips_div_s_b, NoItinerary, MSA128B, MSA128B>; class DIV_S_H_DESC : MSA_3R_DESC_BASE<"div_s.h", int_mips_div_s_h, NoItinerary, @@ -2299,6 +2319,8 @@ def CEQI_H : CEQI_H_ENC, CEQI_H_DESC, Requires<[HasMSA]>; def CEQI_W : CEQI_W_ENC, CEQI_W_DESC, Requires<[HasMSA]>; def CEQI_D : CEQI_D_ENC, CEQI_D_DESC, Requires<[HasMSA]>; +def CFCMSA : CFCMSA_ENC, CFCMSA_DESC, Requires<[HasMSA]>; + def CLE_S_B : CLE_S_B_ENC, CLE_S_B_DESC, Requires<[HasMSA]>; def CLE_S_H : CLE_S_H_ENC, CLE_S_H_DESC, Requires<[HasMSA]>; def CLE_S_W : CLE_S_W_ENC, CLE_S_W_DESC, Requires<[HasMSA]>; @@ -2347,6 +2369,8 @@ def COPY_U_B : COPY_U_B_ENC, COPY_U_B_DESC, Requires<[HasMSA]>; def COPY_U_H : COPY_U_H_ENC, COPY_U_H_DESC, Requires<[HasMSA]>; def COPY_U_W : COPY_U_W_ENC, COPY_U_W_DESC, Requires<[HasMSA]>; +def CTCMSA : CTCMSA_ENC, CTCMSA_DESC, Requires<[HasMSA]>; + def DIV_S_B : DIV_S_B_ENC, DIV_S_B_DESC, Requires<[HasMSA]>; def DIV_S_H : DIV_S_H_ENC, DIV_S_H_DESC, Requires<[HasMSA]>; def DIV_S_W : DIV_S_W_ENC, DIV_S_W_DESC, Requires<[HasMSA]>; diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 03d09a6315e..ee81bae8295 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -167,6 +167,16 @@ getReservedRegs(const MachineFunction &MF) const { Reserved.set(Mips::DSPEFI); Reserved.set(Mips::DSPOutFlag); + // Reserve MSA control registers. + Reserved.set(Mips::MSAIR); + Reserved.set(Mips::MSACSR); + Reserved.set(Mips::MSAAccess); + Reserved.set(Mips::MSASave); + Reserved.set(Mips::MSAModify); + Reserved.set(Mips::MSARequest); + Reserved.set(Mips::MSAMap); + Reserved.set(Mips::MSAUnmap); + // Reserve RA if in mips16 mode. if (Subtarget.inMips16Mode()) { Reserved.set(Mips::RA); diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index 22c489090d8..cef5ebfd3eb 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -231,6 +231,16 @@ let Namespace = "Mips" in { def DSPOutFlag : RegisterWithSubRegs<"", [DSPOutFlag16_19, DSPOutFlag20, DSPOutFlag21, DSPOutFlag22, DSPOutFlag23]>; + + // MSA-ASE control registers. + def MSAIR : Register<"0">; + def MSACSR : Register<"1">; + def MSAAccess : Register<"2">; + def MSASave : Register<"3">; + def MSAModify : Register<"4">; + def MSARequest : Register<"5">; + def MSAMap : Register<"6">; + def MSAUnmap : Register<"7">; } //===----------------------------------------------------------------------===// @@ -329,6 +339,9 @@ def MSA128W: RegisterClass<"Mips", [v4i32, v4f32], 128, def MSA128D: RegisterClass<"Mips", [v2i64, v2f64], 128, (sequence "W%u", 0, 31)>; +def MSACtrl: RegisterClass<"Mips", [i32], 32, (add + MSAIR, MSACSR, MSAAccess, MSASave, MSAModify, MSARequest, MSAMap, MSAUnmap)>; + // Hi/Lo Registers def LO32 : RegisterClass<"Mips", [i32], 32, (add LO0)>; def HI32 : RegisterClass<"Mips", [i32], 32, (add HI0)>; diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 203196e6261..221aedacd37 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -66,6 +66,21 @@ void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, MIB.addReg(Mips::DSPEFI, Flag); } +unsigned MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const { + switch (cast(RegIdx)->getZExtValue()) { + default: + llvm_unreachable("Could not map int to register"); + case 0: return Mips::MSAIR; + case 1: return Mips::MSACSR; + case 2: return Mips::MSAAccess; + case 3: return Mips::MSASave; + case 4: return Mips::MSAModify; + case 5: return Mips::MSARequest; + case 6: return Mips::MSAMap; + case 7: return Mips::MSAUnmap; + } +} + bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr& MI) { unsigned DstReg = 0, ZeroReg = 0; @@ -432,6 +447,39 @@ std::pair MipsSEDAGToDAGISel::selectNode(SDNode *Node) { return std::make_pair(true, RegOpnd); } + case ISD::INTRINSIC_W_CHAIN: { + switch (cast(Node->getOperand(1))->getZExtValue()) { + default: + break; + + case Intrinsic::mips_cfcmsa: { + SDValue ChainIn = Node->getOperand(0); + SDValue RegIdx = Node->getOperand(2); + SDValue Reg = CurDAG->getCopyFromReg(ChainIn, DL, + getMSACtrlReg(RegIdx), MVT::i32); + return std::make_pair(true, Reg.getNode()); + } + } + break; + } + + case ISD::INTRINSIC_VOID: { + switch (cast(Node->getOperand(1))->getZExtValue()) { + default: + break; + + case Intrinsic::mips_ctcmsa: { + SDValue ChainIn = Node->getOperand(0); + SDValue RegIdx = Node->getOperand(2); + SDValue Value = Node->getOperand(3); + SDValue ChainOut = CurDAG->getCopyToReg(ChainIn, DL, + getMSACtrlReg(RegIdx), Value); + return std::make_pair(true, ChainOut.getNode()); + } + } + break; + } + case MipsISD::ThreadPointer: { EVT PtrVT = getTargetLowering()->getPointerTy(); unsigned RdhwrOpc, DestReg; diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.h b/lib/Target/Mips/MipsSEISelDAGToDAG.h index 09a15b01f03..9961934bd87 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -30,6 +30,8 @@ private: void addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, MachineFunction &MF); + unsigned getMSACtrlReg(const SDValue RegIdx) const; + bool replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&); std::pair selectMULT(SDNode *N, unsigned Opc, SDLoc dl, diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index e7967a8dea7..374837e37d2 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -110,6 +110,8 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); return; } + else if (Mips::MSACtrlRegClass.contains(SrcReg)) + Opc = Mips::CFCMSA; } else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg. if (Mips::CCRRegClass.contains(DestReg)) @@ -130,6 +132,8 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, .addReg(DestReg, RegState::ImplicitDefine); return; } + else if (Mips::MSACtrlRegClass.contains(DestReg)) + Opc = Mips::CTCMSA; } else if (Mips::FGR32RegClass.contains(DestReg, SrcReg)) Opc = Mips::FMOV_S; diff --git a/test/CodeGen/Mips/msa/elm_cxcmsa.ll b/test/CodeGen/Mips/msa/elm_cxcmsa.ll new file mode 100644 index 00000000000..383c4ae8b37 --- /dev/null +++ b/test/CodeGen/Mips/msa/elm_cxcmsa.ll @@ -0,0 +1,167 @@ +; Test the MSA ctcmsa and cfcmsa intrinsics (which are encoded with the ELM +; instruction format). + +; RUN: llc -march=mips -mattr=+msa < %s | FileCheck %s + +define i32 @msa_ir_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 0) + ret i32 %0 +} + +; CHECK: msa_ir_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $0 +; CHECK: .size msa_ir_cfcmsa_test +; +define i32 @msa_csr_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 1) + ret i32 %0 +} + +; CHECK: msa_csr_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $1 +; CHECK: .size msa_csr_cfcmsa_test +; +define i32 @msa_access_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 2) + ret i32 %0 +} + +; CHECK: msa_access_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $2 +; CHECK: .size msa_access_cfcmsa_test +; +define i32 @msa_save_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 3) + ret i32 %0 +} + +; CHECK: msa_save_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $3 +; CHECK: .size msa_save_cfcmsa_test +; +define i32 @msa_modify_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 4) + ret i32 %0 +} + +; CHECK: msa_modify_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $4 +; CHECK: .size msa_modify_cfcmsa_test +; +define i32 @msa_request_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 5) + ret i32 %0 +} + +; CHECK: msa_request_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $5 +; CHECK: .size msa_request_cfcmsa_test +; +define i32 @msa_map_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 6) + ret i32 %0 +} + +; CHECK: msa_map_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $6 +; CHECK: .size msa_map_cfcmsa_test +; +define i32 @msa_unmap_cfcmsa_test() nounwind { +entry: + %0 = tail call i32 @llvm.mips.cfcmsa(i32 7) + ret i32 %0 +} + +; CHECK: msa_unmap_cfcmsa_test: +; CHECK: cfcmsa $[[R1:[0-9]+]], $7 +; CHECK: .size msa_unmap_cfcmsa_test +; +define void @msa_ir_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 0, i32 1) + ret void +} + +; CHECK: msa_ir_ctcmsa_test: +; CHECK: ctcmsa $0 +; CHECK: .size msa_ir_ctcmsa_test +; +define void @msa_csr_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 1, i32 1) + ret void +} + +; CHECK: msa_csr_ctcmsa_test: +; CHECK: ctcmsa $1 +; CHECK: .size msa_csr_ctcmsa_test +; +define void @msa_access_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 2, i32 1) + ret void +} + +; CHECK: msa_access_ctcmsa_test: +; CHECK: ctcmsa $2 +; CHECK: .size msa_access_ctcmsa_test +; +define void @msa_save_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 3, i32 1) + ret void +} + +; CHECK: msa_save_ctcmsa_test: +; CHECK: ctcmsa $3 +; CHECK: .size msa_save_ctcmsa_test +; +define void @msa_modify_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 4, i32 1) + ret void +} + +; CHECK: msa_modify_ctcmsa_test: +; CHECK: ctcmsa $4 +; CHECK: .size msa_modify_ctcmsa_test +; +define void @msa_request_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 5, i32 1) + ret void +} + +; CHECK: msa_request_ctcmsa_test: +; CHECK: ctcmsa $5 +; CHECK: .size msa_request_ctcmsa_test +; +define void @msa_map_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 6, i32 1) + ret void +} + +; CHECK: msa_map_ctcmsa_test: +; CHECK: ctcmsa $6 +; CHECK: .size msa_map_ctcmsa_test +; +define void @msa_unmap_ctcmsa_test() nounwind { +entry: + tail call void @llvm.mips.ctcmsa(i32 7, i32 1) + ret void +} + +; CHECK: msa_unmap_ctcmsa_test: +; CHECK: ctcmsa $7 +; CHECK: .size msa_unmap_ctcmsa_test +; +declare i32 @llvm.mips.cfcmsa(i32) nounwind +declare void @llvm.mips.ctcmsa(i32, i32) nounwind