mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[mips][msa] Implemented insert_vector_elt for v4f32 and v2f64.
For v4f32 and v2f64, INSERT_VECTOR_ELT is matched by a pseudo-insn which is later expanded to appropriate insve.[wd] insns. llvm-svn: 191515
This commit is contained in:
parent
0bb1b5a37f
commit
8c83ddcdd2
@ -1242,6 +1242,15 @@ class MSA_INSERT_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
|
||||
string Constraints = "$wd = $wd_in";
|
||||
}
|
||||
|
||||
class MSA_INSERT_PSEUDO_BASE<SDPatternOperator OpNode, ValueType Ty,
|
||||
RegisterClass RCWD, RegisterClass RCFS> :
|
||||
MipsPseudo<(outs RCWD:$wd), (ins RCWD:$wd_in, uimm6:$n, RCFS:$fs),
|
||||
[(set RCWD:$wd, (OpNode (Ty RCWD:$wd_in), RCFS:$fs,
|
||||
immZExt6:$n))]> {
|
||||
bit usesCustomInserter = 1;
|
||||
string Constraints = "$wd = $wd_in";
|
||||
}
|
||||
|
||||
class MSA_INSVE_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
|
||||
RegisterClass RCWD, RegisterClass RCWS = RCWD,
|
||||
InstrItinClass itin = NoItinerary> {
|
||||
@ -1954,6 +1963,11 @@ class INSERT_H_DESC : MSA_INSERT_DESC_BASE<"insert.h", vinsert_v8i16, MSA128H,
|
||||
class INSERT_W_DESC : MSA_INSERT_DESC_BASE<"insert.w", vinsert_v4i32, MSA128W,
|
||||
GPR32>;
|
||||
|
||||
class INSERT_FW_PSEUDO_DESC : MSA_INSERT_PSEUDO_BASE<vector_insert, v4f32,
|
||||
MSA128W, FGR32>;
|
||||
class INSERT_FD_PSEUDO_DESC : MSA_INSERT_PSEUDO_BASE<vector_insert, v2f64,
|
||||
MSA128D, FGR64>;
|
||||
|
||||
class INSVE_B_DESC : MSA_INSVE_DESC_BASE<"insve.b", int_mips_insve_b, MSA128B>;
|
||||
class INSVE_H_DESC : MSA_INSVE_DESC_BASE<"insve.h", int_mips_insve_h, MSA128H>;
|
||||
class INSVE_W_DESC : MSA_INSVE_DESC_BASE<"insve.w", int_mips_insve_w, MSA128W>;
|
||||
@ -2827,11 +2841,17 @@ def INSERT_B : INSERT_B_ENC, INSERT_B_DESC;
|
||||
def INSERT_H : INSERT_H_ENC, INSERT_H_DESC;
|
||||
def INSERT_W : INSERT_W_ENC, INSERT_W_DESC;
|
||||
|
||||
// INSERT_FW_PSEUDO defined after INSVE_W
|
||||
// INSERT_FD_PSEUDO defined after INSVE_D
|
||||
|
||||
def INSVE_B : INSVE_B_ENC, INSVE_B_DESC;
|
||||
def INSVE_H : INSVE_H_ENC, INSVE_H_DESC;
|
||||
def INSVE_W : INSVE_W_ENC, INSVE_W_DESC;
|
||||
def INSVE_D : INSVE_D_ENC, INSVE_D_DESC;
|
||||
|
||||
def INSERT_FW_PSEUDO : INSERT_FW_PSEUDO_DESC;
|
||||
def INSERT_FD_PSEUDO : INSERT_FD_PSEUDO_DESC;
|
||||
|
||||
def LD_B: LD_B_ENC, LD_B_DESC;
|
||||
def LD_H: LD_H_ENC, LD_H_DESC;
|
||||
def LD_W: LD_W_ENC, LD_W_DESC;
|
||||
|
@ -207,6 +207,7 @@ addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
|
||||
setOperationAction(ISD::STORE, Ty, Legal);
|
||||
setOperationAction(ISD::BITCAST, Ty, Legal);
|
||||
setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Legal);
|
||||
setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Legal);
|
||||
|
||||
if (Ty != MVT::v8f16) {
|
||||
setOperationAction(ISD::FABS, Ty, Legal);
|
||||
@ -831,6 +832,10 @@ MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
return emitCOPY_FW(MI, BB);
|
||||
case Mips::COPY_FD_PSEUDO:
|
||||
return emitCOPY_FD(MI, BB);
|
||||
case Mips::INSERT_FW_PSEUDO:
|
||||
return emitINSERT_FW(MI, BB);
|
||||
case Mips::INSERT_FD_PSEUDO:
|
||||
return emitINSERT_FD(MI, BB);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2315,3 +2320,57 @@ emitCOPY_FD(MachineInstr *MI, MachineBasicBlock *BB) const{
|
||||
MI->eraseFromParent(); // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
||||
|
||||
// Emit the INSERT_FW pseudo instruction.
|
||||
//
|
||||
// insert_fw_pseudo $wd, $wd_in, $n, $fs
|
||||
// =>
|
||||
// subreg_to_reg $wt:sub_lo, $fs
|
||||
// insve_w $wd[$n], $wd_in, $wt[0]
|
||||
MachineBasicBlock * MipsSETargetLowering::
|
||||
emitINSERT_FW(MachineInstr *MI, MachineBasicBlock *BB) const{
|
||||
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
|
||||
MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
unsigned Wd = MI->getOperand(0).getReg();
|
||||
unsigned Wd_in = MI->getOperand(1).getReg();
|
||||
unsigned Lane = MI->getOperand(2).getImm();
|
||||
unsigned Fs = MI->getOperand(3).getReg();
|
||||
unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
|
||||
|
||||
BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
|
||||
.addImm(0).addReg(Fs).addImm(Mips::sub_lo);
|
||||
BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_W), Wd)
|
||||
.addReg(Wd_in).addImm(Lane).addReg(Wt);
|
||||
|
||||
MI->eraseFromParent(); // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
||||
|
||||
// Emit the INSERT_FD pseudo instruction.
|
||||
//
|
||||
// insert_fd_pseudo $wd, $fs, n
|
||||
// =>
|
||||
// subreg_to_reg $wt:sub_64, $fs
|
||||
// insve_d $wd[$n], $wd_in, $wt[0]
|
||||
MachineBasicBlock * MipsSETargetLowering::
|
||||
emitINSERT_FD(MachineInstr *MI, MachineBasicBlock *BB) const{
|
||||
assert(Subtarget->isFP64bit());
|
||||
|
||||
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
|
||||
MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
unsigned Wd = MI->getOperand(0).getReg();
|
||||
unsigned Wd_in = MI->getOperand(1).getReg();
|
||||
unsigned Lane = MI->getOperand(2).getImm();
|
||||
unsigned Fs = MI->getOperand(3).getReg();
|
||||
unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
|
||||
|
||||
BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
|
||||
.addImm(0).addReg(Fs).addImm(Mips::sub_64);
|
||||
BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_D), Wd)
|
||||
.addReg(Wd_in).addImm(Lane).addReg(Wt);
|
||||
|
||||
MI->eraseFromParent(); // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
||||
|
@ -90,6 +90,12 @@ namespace llvm {
|
||||
/// \brief Emit the COPY_FD pseudo instruction
|
||||
MachineBasicBlock *emitCOPY_FD(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
/// \brief Emit the INSERT_FW pseudo instruction
|
||||
MachineBasicBlock *emitINSERT_FW(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
/// \brief Emit the INSERT_FD pseudo instruction
|
||||
MachineBasicBlock *emitINSERT_FD(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -135,3 +135,37 @@ define double @extract_v2f64_elt0() nounwind {
|
||||
ret double %3
|
||||
; MIPS32: .size extract_v2f64_elt0
|
||||
}
|
||||
|
||||
define void @insert_v4f32(float %a) nounwind {
|
||||
; MIPS32: insert_v4f32:
|
||||
|
||||
%1 = load <4 x float>* @v4f32
|
||||
; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
|
||||
|
||||
%2 = insertelement <4 x float> %1, float %a, i32 1
|
||||
; float argument passed in $f12
|
||||
; MIPS32-DAG: insve.w [[R1]][1], $w12[0]
|
||||
|
||||
store <4 x float> %2, <4 x float>* @v4f32
|
||||
; MIPS32-DAG: st.w [[R1]]
|
||||
|
||||
ret void
|
||||
; MIPS32: .size insert_v4f32
|
||||
}
|
||||
|
||||
define void @insert_v2f64(double %a) nounwind {
|
||||
; MIPS32: insert_v2f64:
|
||||
|
||||
%1 = load <2 x double>* @v2f64
|
||||
; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]],
|
||||
|
||||
%2 = insertelement <2 x double> %1, double %a, i32 1
|
||||
; double argument passed in $f12
|
||||
; MIPS32-DAG: insve.d [[R1]][1], $w12[0]
|
||||
|
||||
store <2 x double> %2, <2 x double>* @v2f64
|
||||
; MIPS32-DAG: st.d [[R1]]
|
||||
|
||||
ret void
|
||||
; MIPS32: .size insert_v2f64
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user