diff options
author | Daniel Sanders <daniel.sanders@imgtec.com> | 2013-09-27 12:17:32 +0000 |
---|---|---|
committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2013-09-27 12:17:32 +0000 |
commit | b4691b495d867a863aa12de57d45bc6a93e4df78 (patch) | |
tree | 66e391e65dae3280bfa5455f4b96dfff4718b81f /lib | |
parent | 4cc117883d98c67d90d5fe15a6dc63af8e9dcf7a (diff) | |
download | external_llvm-b4691b495d867a863aa12de57d45bc6a93e4df78.zip external_llvm-b4691b495d867a863aa12de57d45bc6a93e4df78.tar.gz external_llvm-b4691b495d867a863aa12de57d45bc6a93e4df78.tar.bz2 |
[mips][msa] Implemented extract_vector_elt for v4f32 or v2f64
For v4f32 and v2f64, EXTRACT_VECTOR_ELT is matched by a pseudo-insn which may
be expanded to subregister copies and/or instructions as appropriate.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191514 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Mips/MipsMSAInstrInfo.td | 15 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEISelLowering.cpp | 87 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEISelLowering.h | 6 |
3 files changed, 104 insertions, 4 deletions
diff --git a/lib/Target/Mips/MipsMSAInstrInfo.td b/lib/Target/Mips/MipsMSAInstrInfo.td index 7ed2f84..13b5775 100644 --- a/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/lib/Target/Mips/MipsMSAInstrInfo.td @@ -1076,6 +1076,13 @@ class MSA_COPY_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass Itinerary = itin; } +class MSA_COPY_PSEUDO_BASE<SDPatternOperator OpNode, ValueType VecTy, + RegisterClass RCD, RegisterClass RCWS> : + MipsPseudo<(outs RCD:$wd), (ins RCWS:$ws, uimm4:$n), + [(set RCD:$wd, (OpNode (VecTy RCWS:$ws), immZExt4:$n))]> { + bit usesCustomInserter = 1; +} + class MSA_I5_DESC_BASE<string instr_asm, SDPatternOperator OpNode, SplatComplexPattern SplatImm, RegisterClass RCWD, RegisterClass RCWS = RCWD, @@ -1581,6 +1588,11 @@ class COPY_U_H_DESC : MSA_COPY_DESC_BASE<"copy_u.h", vextract_zext_i16, v8i16, class COPY_U_W_DESC : MSA_COPY_DESC_BASE<"copy_u.w", vextract_zext_i32, v4i32, GPR32, MSA128W>; +class COPY_FW_PSEUDO_DESC : MSA_COPY_PSEUDO_BASE<vector_extract, v4f32, FGR32, + MSA128W>; +class COPY_FD_PSEUDO_DESC : MSA_COPY_PSEUDO_BASE<vector_extract, v2f64, FGR64, + MSA128D>; + class CTCMSA_DESC { dag OutOperandList = (outs); dag InOperandList = (ins MSACtrl:$cd, GPR32:$rs); @@ -2579,6 +2591,9 @@ def COPY_U_B : COPY_U_B_ENC, COPY_U_B_DESC; def COPY_U_H : COPY_U_H_ENC, COPY_U_H_DESC; def COPY_U_W : COPY_U_W_ENC, COPY_U_W_DESC; +def COPY_FW_PSEUDO : COPY_FW_PSEUDO_DESC; +def COPY_FD_PSEUDO : COPY_FD_PSEUDO_DESC; + def CTCMSA : CTCMSA_ENC, CTCMSA_DESC; def DIV_S_B : DIV_S_B_ENC, DIV_S_B_DESC; diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 84db5ce..99c7019 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -827,6 +827,10 @@ MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return emitMSACBranchPseudo(MI, BB, Mips::BZ_D); case Mips::SZ_V_PSEUDO: return emitMSACBranchPseudo(MI, BB, Mips::BZ_V); + case Mips::COPY_FW_PSEUDO: + return emitCOPY_FW(MI, BB); + case Mips::COPY_FD_PSEUDO: + return emitCOPY_FD(MI, BB); } } @@ -1662,10 +1666,19 @@ lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); EVT ResTy = Op->getValueType(0); SDValue Op0 = Op->getOperand(0); - SDValue Op1 = Op->getOperand(1); - EVT EltTy = Op0->getValueType(0).getVectorElementType(); - return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1, - DAG.getValueType(EltTy)); + EVT VecTy = Op0->getValueType(0); + + if (!VecTy.is128BitVector()) + return SDValue(); + + if (ResTy.isInteger()) { + SDValue Op1 = Op->getOperand(1); + EVT EltTy = VecTy.getVectorElementType(); + return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1, + DAG.getValueType(EltTy)); + } + + return Op; } static bool isConstantOrUndef(const SDValue Op) { @@ -2236,3 +2249,69 @@ emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB, MI->eraseFromParent(); // The pseudo instruction is gone now. return Sink; } + +// Emit the COPY_FW pseudo instruction. +// +// copy_fw_pseudo $fd, $ws, n +// => +// copy_u_w $rt, $ws, $n +// mtc1 $rt, $fd +// +// When n is zero, the equivalent operation can be performed with (potentially) +// zero instructions due to register overlaps. This optimization is never valid +// for lane 1 because it would require FR=0 mode which isn't supported by MSA. +MachineBasicBlock * MipsSETargetLowering:: +emitCOPY_FW(MachineInstr *MI, MachineBasicBlock *BB) const{ + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); + DebugLoc DL = MI->getDebugLoc(); + unsigned Fd = MI->getOperand(0).getReg(); + unsigned Ws = MI->getOperand(1).getReg(); + unsigned Lane = MI->getOperand(2).getImm(); + + if (Lane == 0) + BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, 0, Mips::sub_lo); + else { + unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass); + + BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wt).addReg(Ws).addImm(1); + BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_lo); + } + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return BB; +} + +// Emit the COPY_FD pseudo instruction. +// +// copy_fd_pseudo $fd, $ws, n +// => +// splati.d $wt, $ws, $n +// copy $fd, $wt:sub_64 +// +// When n is zero, the equivalent operation can be performed with (potentially) +// zero instructions due to register overlaps. This optimization is always +// valid because FR=1 mode which is the only supported mode in MSA. +MachineBasicBlock * MipsSETargetLowering:: +emitCOPY_FD(MachineInstr *MI, MachineBasicBlock *BB) const{ + assert(Subtarget->isFP64bit()); + + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); + unsigned Fd = MI->getOperand(0).getReg(); + unsigned Ws = MI->getOperand(1).getReg(); + unsigned Lane = MI->getOperand(2).getImm() * 2; + DebugLoc DL = MI->getDebugLoc(); + + if (Lane == 0) + BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, 0, Mips::sub_64); + else { + unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass); + + BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wt).addReg(Ws).addImm(1); + BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_64); + } + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return BB; +} diff --git a/lib/Target/Mips/MipsSEISelLowering.h b/lib/Target/Mips/MipsSEISelLowering.h index 9b69fb5..03f1cc5 100644 --- a/lib/Target/Mips/MipsSEISelLowering.h +++ b/lib/Target/Mips/MipsSEISelLowering.h @@ -84,6 +84,12 @@ namespace llvm { MachineBasicBlock *emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB, unsigned BranchOp) const; + /// \brief Emit the COPY_FW pseudo instruction + MachineBasicBlock *emitCOPY_FW(MachineInstr *MI, + MachineBasicBlock *BB) const; + /// \brief Emit the COPY_FD pseudo instruction + MachineBasicBlock *emitCOPY_FD(MachineInstr *MI, + MachineBasicBlock *BB) const; }; } |