mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[PowerPC] Implement Vector String Isolate Builtins in Clang/LLVM
This patch implements the vector string isolate (predicate and non-predicate versions) builtins. The predicate builtins are custom selected within PPCISelDAGToDAG. Differential Revision: https://reviews.llvm.org/D87671
This commit is contained in:
parent
8864893cb8
commit
4778b6148c
@ -501,6 +501,25 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
|
|||||||
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
|
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
|
||||||
[IntrNoMem]>;
|
[IntrNoMem]>;
|
||||||
|
|
||||||
|
// P10 Vector String Isolate Intrinsics.
|
||||||
|
def int_ppc_altivec_vstribr : GCCBuiltin<"__builtin_altivec_vstribr">,
|
||||||
|
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_altivec_vstribl : GCCBuiltin<"__builtin_altivec_vstribl">,
|
||||||
|
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_altivec_vstrihr : GCCBuiltin<"__builtin_altivec_vstrihr">,
|
||||||
|
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_altivec_vstrihl : GCCBuiltin<"__builtin_altivec_vstrihl">,
|
||||||
|
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
|
||||||
|
// Predicate Intrinsics: The first operand specifies interpretation of CR6.
|
||||||
|
def int_ppc_altivec_vstribr_p : GCCBuiltin<"__builtin_altivec_vstribr_p">,
|
||||||
|
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_altivec_vstribl_p : GCCBuiltin<"__builtin_altivec_vstribl_p">,
|
||||||
|
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_altivec_vstrihr_p : GCCBuiltin<"__builtin_altivec_vstrihr_p">,
|
||||||
|
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||||
|
def int_ppc_altivec_vstrihl_p : GCCBuiltin<"__builtin_altivec_vstrihl_p">,
|
||||||
|
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
|
||||||
|
|
||||||
// P10 Vector Centrifuge Builtin.
|
// P10 Vector Centrifuge Builtin.
|
||||||
def int_ppc_altivec_vcfuged : GCCBuiltin<"__builtin_altivec_vcfuged">,
|
def int_ppc_altivec_vcfuged : GCCBuiltin<"__builtin_altivec_vcfuged">,
|
||||||
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
|
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "llvm/IR/GlobalValue.h"
|
#include "llvm/IR/GlobalValue.h"
|
||||||
#include "llvm/IR/InlineAsm.h"
|
#include "llvm/IR/InlineAsm.h"
|
||||||
#include "llvm/IR/InstrTypes.h"
|
#include "llvm/IR/InstrTypes.h"
|
||||||
|
#include "llvm/IR/IntrinsicsPowerPC.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/CodeGen.h"
|
#include "llvm/Support/CodeGen.h"
|
||||||
@ -4677,6 +4678,45 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ISD::INTRINSIC_WO_CHAIN: {
|
||||||
|
if (!PPCSubTarget->isISA3_1())
|
||||||
|
break;
|
||||||
|
unsigned Opcode = 0;
|
||||||
|
switch (N->getConstantOperandVal(0)) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case Intrinsic::ppc_altivec_vstribr_p:
|
||||||
|
Opcode = PPC::VSTRIBR_rec;
|
||||||
|
break;
|
||||||
|
case Intrinsic::ppc_altivec_vstribl_p:
|
||||||
|
Opcode = PPC::VSTRIBL_rec;
|
||||||
|
break;
|
||||||
|
case Intrinsic::ppc_altivec_vstrihr_p:
|
||||||
|
Opcode = PPC::VSTRIHR_rec;
|
||||||
|
break;
|
||||||
|
case Intrinsic::ppc_altivec_vstrihl_p:
|
||||||
|
Opcode = PPC::VSTRIHL_rec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!Opcode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Generate the appropriate vector string isolate intrinsic to match.
|
||||||
|
EVT VTs[] = {MVT::v16i8, MVT::Glue};
|
||||||
|
SDValue VecStrOp =
|
||||||
|
SDValue(CurDAG->getMachineNode(Opcode, dl, VTs, N->getOperand(2)), 0);
|
||||||
|
// Vector string isolate instructions update the EQ bit of CR6.
|
||||||
|
// Generate a SETBC instruction to extract the bit and place it in a GPR.
|
||||||
|
SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_eq, dl, MVT::i32);
|
||||||
|
SDValue CR6Reg = CurDAG->getRegister(PPC::CR6, MVT::i32);
|
||||||
|
SDValue CRBit = SDValue(
|
||||||
|
CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
|
||||||
|
CR6Reg, SubRegIdx, VecStrOp.getValue(1)),
|
||||||
|
0);
|
||||||
|
CurDAG->SelectNodeTo(N, PPC::SETBC, MVT::i32, CRBit);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case ISD::SETCC:
|
case ISD::SETCC:
|
||||||
case ISD::STRICT_FSETCC:
|
case ISD::STRICT_FSETCC:
|
||||||
case ISD::STRICT_FSETCCS:
|
case ISD::STRICT_FSETCCS:
|
||||||
|
@ -1020,13 +1020,21 @@ let Predicates = [IsISA3_1] in {
|
|||||||
v16i8:$VRB,
|
v16i8:$VRB,
|
||||||
i32:$SH))]>;
|
i32:$SH))]>;
|
||||||
defm VSTRIBR : VXForm_VTB5_RCr<13, 1, (outs vrrc:$vT), (ins vrrc:$vB),
|
defm VSTRIBR : VXForm_VTB5_RCr<13, 1, (outs vrrc:$vT), (ins vrrc:$vB),
|
||||||
"vstribr", "$vT, $vB", IIC_VecGeneral, []>;
|
"vstribr", "$vT, $vB", IIC_VecGeneral,
|
||||||
|
[(set v16i8:$vT,
|
||||||
|
(int_ppc_altivec_vstribr v16i8:$vB))]>;
|
||||||
defm VSTRIBL : VXForm_VTB5_RCr<13, 0, (outs vrrc:$vT), (ins vrrc:$vB),
|
defm VSTRIBL : VXForm_VTB5_RCr<13, 0, (outs vrrc:$vT), (ins vrrc:$vB),
|
||||||
"vstribl", "$vT, $vB", IIC_VecGeneral, []>;
|
"vstribl", "$vT, $vB", IIC_VecGeneral,
|
||||||
|
[(set v16i8:$vT,
|
||||||
|
(int_ppc_altivec_vstribl v16i8:$vB))]>;
|
||||||
defm VSTRIHR : VXForm_VTB5_RCr<13, 3, (outs vrrc:$vT), (ins vrrc:$vB),
|
defm VSTRIHR : VXForm_VTB5_RCr<13, 3, (outs vrrc:$vT), (ins vrrc:$vB),
|
||||||
"vstrihr", "$vT, $vB", IIC_VecGeneral, []>;
|
"vstrihr", "$vT, $vB", IIC_VecGeneral,
|
||||||
|
[(set v8i16:$vT,
|
||||||
|
(int_ppc_altivec_vstrihr v8i16:$vB))]>;
|
||||||
defm VSTRIHL : VXForm_VTB5_RCr<13, 2, (outs vrrc:$vT), (ins vrrc:$vB),
|
defm VSTRIHL : VXForm_VTB5_RCr<13, 2, (outs vrrc:$vT), (ins vrrc:$vB),
|
||||||
"vstrihl", "$vT, $vB", IIC_VecGeneral, []>;
|
"vstrihl", "$vT, $vB", IIC_VecGeneral,
|
||||||
|
[(set v8i16:$vT,
|
||||||
|
(int_ppc_altivec_vstrihl v8i16:$vB))]>;
|
||||||
def VINSW :
|
def VINSW :
|
||||||
VXForm_1<207, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, gprc:$rB),
|
VXForm_1<207, (outs vrrc:$vD), (ins vrrc:$vDi, u4imm:$UIM, gprc:$rB),
|
||||||
"vinsw $vD, $rB, $UIM", IIC_VecGeneral,
|
"vinsw $vD, $rB, $UIM", IIC_VecGeneral,
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
|
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
|
||||||
; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
|
; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
|
||||||
; RUN: FileCheck %s
|
; RUN: FileCheck %s
|
||||||
|
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
|
||||||
|
; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
|
||||||
|
; RUN: FileCheck %s
|
||||||
|
|
||||||
; These test cases aim to test the vector string isolate builtins on Power10.
|
; These test cases aim to test the vector string isolate builtins on Power10.
|
||||||
|
|
||||||
@ -27,3 +30,97 @@ entry:
|
|||||||
%tmp = tail call <16 x i8> @llvm.ppc.altivec.vclrrb(<16 x i8> %a, i32 %n)
|
%tmp = tail call <16 x i8> @llvm.ppc.altivec.vclrrb(<16 x i8> %a, i32 %n)
|
||||||
ret <16 x i8> %tmp
|
ret <16 x i8> %tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare <16 x i8> @llvm.ppc.altivec.vstribr(<16 x i8>)
|
||||||
|
declare <16 x i8> @llvm.ppc.altivec.vstribl(<16 x i8>)
|
||||||
|
declare <8 x i16> @llvm.ppc.altivec.vstrihr(<8 x i16>)
|
||||||
|
declare <8 x i16> @llvm.ppc.altivec.vstrihl(<8 x i16>)
|
||||||
|
|
||||||
|
declare i32 @llvm.ppc.altivec.vstribr.p(i32, <16 x i8>)
|
||||||
|
declare i32 @llvm.ppc.altivec.vstribl.p(i32, <16 x i8>)
|
||||||
|
declare i32 @llvm.ppc.altivec.vstrihr.p(i32, <8 x i16>)
|
||||||
|
declare i32 @llvm.ppc.altivec.vstrihl.p(i32, <8 x i16>)
|
||||||
|
|
||||||
|
define <16 x i8> @test_vstribr(<16 x i8> %a) {
|
||||||
|
; CHECK-LABEL: test_vstribr:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstribr v2, v2
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call <16 x i8> @llvm.ppc.altivec.vstribr(<16 x i8> %a)
|
||||||
|
ret <16 x i8> %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define <16 x i8> @test_vstribl(<16 x i8> %a) {
|
||||||
|
; CHECK-LABEL: test_vstribl:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstribl v2, v2
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call <16 x i8> @llvm.ppc.altivec.vstribl(<16 x i8>%a)
|
||||||
|
ret <16 x i8> %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define <8 x i16> @test_vstrihr(<8 x i16> %a) {
|
||||||
|
; CHECK-LABEL: test_vstrihr:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstrihr v2, v2
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call <8 x i16> @llvm.ppc.altivec.vstrihr(<8 x i16> %a)
|
||||||
|
ret <8 x i16> %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define <8 x i16> @test_vstrihl(<8 x i16> %a) {
|
||||||
|
; CHECK-LABEL: test_vstrihl:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstrihl v2, v2
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call <8 x i16> @llvm.ppc.altivec.vstrihl(<8 x i16> %a)
|
||||||
|
ret <8 x i16> %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @test_vstribr_p(<16 x i8> %a) {
|
||||||
|
; CHECK-LABEL: test_vstribr_p:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstribr. v2, v2
|
||||||
|
; CHECK-NEXT: setbc r3, 4*cr6+eq
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call i32 @llvm.ppc.altivec.vstribr.p(i32 1, <16 x i8> %a)
|
||||||
|
ret i32 %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @test_vstribl_p(<16 x i8> %a) {
|
||||||
|
; CHECK-LABEL: test_vstribl_p:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstribl. v2, v2
|
||||||
|
; CHECK-NEXT: setbc r3, 4*cr6+eq
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call i32 @llvm.ppc.altivec.vstribl.p(i32 1, <16 x i8> %a)
|
||||||
|
ret i32 %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @test_vstrihr_p(<8 x i16> %a) {
|
||||||
|
; CHECK-LABEL: test_vstrihr_p:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstrihr. v2, v2
|
||||||
|
; CHECK-NEXT: setbc r3, 4*cr6+eq
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call i32 @llvm.ppc.altivec.vstrihr.p(i32 1, <8 x i16> %a)
|
||||||
|
ret i32 %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @test_vstrihl_p(<8 x i16> %a) {
|
||||||
|
; CHECK-LABEL: test_vstrihl_p:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: vstrihl. v2, v2
|
||||||
|
; CHECK-NEXT: setbc r3, 4*cr6+eq
|
||||||
|
; CHECK-NEXT: blr
|
||||||
|
entry:
|
||||||
|
%tmp = tail call i32 @llvm.ppc.altivec.vstrihl.p(i32 1, <8 x i16> %a)
|
||||||
|
ret i32 %tmp
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user