forked from OSchip/llvm-project
[Hexagon] Add support for "new" circular buffer intrinsics
These instructions have been around for a long time, but we haven't supported intrinsics for them. The "new" vesrions use the CSx register for the start of the buffer instead of the K field in the Mx register. There is a related llvm patch. Patch by Brendon Cahoon. llvm-svn: 328725
This commit is contained in:
parent
440ba3ae5c
commit
1ef2a1f414
|
@ -39,6 +39,29 @@ BUILTIN(__builtin_circ_stw, "i*i*iiIi", "")
|
|||
BUILTIN(__builtin_circ_sth, "s*s*iiIi", "")
|
||||
BUILTIN(__builtin_circ_sthhi, "s*s*iiIi", "")
|
||||
BUILTIN(__builtin_circ_stb, "c*c*iiIi", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrub_pci, "iv*IiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrb_pci, "iv*IiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadruh_pci, "iv*IiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrh_pci, "iv*IiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadri_pci, "iv*IiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrd_pci, "LLiv*IiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrub_pcr, "iv*ivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrb_pcr, "iv*ivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadruh_pcr, "iv*ivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrh_pcr, "iv*ivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadri_pcr, "iv*ivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_L2_loadrd_pcr, "LLiv*ivC*", "")
|
||||
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerb_pci, "vv*IiiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerh_pci, "vv*IiiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerf_pci, "vv*IiiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storeri_pci, "vv*IiiivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerd_pci, "vv*IiiLLivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerb_pcr, "vv*iivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerh_pcr, "vv*iivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerf_pcr, "vv*iivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storeri_pcr, "vv*iivC*", "")
|
||||
BUILTIN(__builtin_HEXAGON_S2_storerd_pcr, "vv*iLLivC*", "")
|
||||
|
||||
// The builtins above are not autogenerated from iset.py.
|
||||
// Make sure you do not overwrite these.
|
||||
|
|
|
@ -10772,6 +10772,54 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID,
|
|||
SmallVector<llvm::Value *, 4> Ops;
|
||||
Intrinsic::ID ID = Intrinsic::not_intrinsic;
|
||||
|
||||
auto MakeCircLd = [&](unsigned IntID, bool HasImm = true) {
|
||||
// The base pointer is passed by address, so it needs to be loaded.
|
||||
Address BP = EmitPointerWithAlignment(E->getArg(0));
|
||||
BP = Address(Builder.CreateBitCast(BP.getPointer(), Int8PtrPtrTy),
|
||||
BP.getAlignment());
|
||||
llvm::Value *Base = Builder.CreateLoad(BP);
|
||||
// Operands are Base, Increment, Modifier, Start.
|
||||
if (HasImm)
|
||||
Ops = { Base, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2)),
|
||||
EmitScalarExpr(E->getArg(3)) };
|
||||
else
|
||||
Ops = { Base, EmitScalarExpr(E->getArg(1)),
|
||||
EmitScalarExpr(E->getArg(2)) };
|
||||
|
||||
llvm::Value *Result = Builder.CreateCall(CGM.getIntrinsic(IntID), Ops);
|
||||
llvm::Value *NewBase = Builder.CreateExtractValue(Result, 1);
|
||||
llvm::Value *LV = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)),
|
||||
NewBase->getType()->getPointerTo());
|
||||
Address Dest = EmitPointerWithAlignment(E->getArg(0));
|
||||
// The intrinsic generates two results. The new value for the base pointer
|
||||
// needs to be stored.
|
||||
Builder.CreateAlignedStore(NewBase, LV, Dest.getAlignment());
|
||||
return Builder.CreateExtractValue(Result, 0);
|
||||
};
|
||||
|
||||
auto MakeCircSt = [&](unsigned IntID, bool HasImm = true) {
|
||||
// The base pointer is passed by address, so it needs to be loaded.
|
||||
Address BP = EmitPointerWithAlignment(E->getArg(0));
|
||||
BP = Address(Builder.CreateBitCast(BP.getPointer(), Int8PtrPtrTy),
|
||||
BP.getAlignment());
|
||||
llvm::Value *Base = Builder.CreateLoad(BP);
|
||||
// Operands are Base, Increment, Modifier, Value, Start.
|
||||
if (HasImm)
|
||||
Ops = { Base, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2)),
|
||||
EmitScalarExpr(E->getArg(3)), EmitScalarExpr(E->getArg(4)) };
|
||||
else
|
||||
Ops = { Base, EmitScalarExpr(E->getArg(1)),
|
||||
EmitScalarExpr(E->getArg(2)), EmitScalarExpr(E->getArg(3)) };
|
||||
|
||||
llvm::Value *NewBase = Builder.CreateCall(CGM.getIntrinsic(IntID), Ops);
|
||||
llvm::Value *LV = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)),
|
||||
NewBase->getType()->getPointerTo());
|
||||
Address Dest = EmitPointerWithAlignment(E->getArg(0));
|
||||
// The intrinsic generates one result, which is the new value for the base
|
||||
// pointer. It needs to be stored.
|
||||
return Builder.CreateAlignedStore(NewBase, LV, Dest.getAlignment());
|
||||
};
|
||||
|
||||
switch (BuiltinID) {
|
||||
case Hexagon::BI__builtin_HEXAGON_V6_vaddcarry:
|
||||
case Hexagon::BI__builtin_HEXAGON_V6_vaddcarry_128B: {
|
||||
|
@ -10817,6 +10865,52 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID,
|
|||
Builder.CreateAlignedStore(Vprd, Base, Dest.getAlignment());
|
||||
return Builder.CreateExtractValue(Result, 0);
|
||||
}
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrub_pci:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrub_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrb_pci:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrb_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadruh_pci:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadruh_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrh_pci:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrh_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadri_pci:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadri_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrd_pci:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrd_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrub_pcr:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrub_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrb_pcr:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrb_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadruh_pcr:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadruh_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrh_pcr:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrh_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadri_pcr:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadri_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_L2_loadrd_pcr:
|
||||
return MakeCircLd(Intrinsic::hexagon_L2_loadrd_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerb_pci:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerb_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerh_pci:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerh_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerf_pci:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerf_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storeri_pci:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storeri_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerd_pci:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerd_pci);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerb_pcr:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerb_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerh_pcr:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerh_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerf_pcr:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerf_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storeri_pcr:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storeri_pcr, /*HasImm=*/false);
|
||||
case Hexagon::BI__builtin_HEXAGON_S2_storerd_pcr:
|
||||
return MakeCircSt(Intrinsic::hexagon_S2_storerd_pcr, /*HasImm=*/false);
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
// REQUIRES: hexagon-registered-target
|
||||
// RUN: %clang_cc1 -triple hexagon-unknown-elf -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: test1
|
||||
// CHECK: @llvm.hexagon.L2.loadrub.pci
|
||||
unsigned char test1(int mod, void *start) {
|
||||
unsigned char *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrub_pci(&base, 4, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test2
|
||||
// CHECK: @llvm.hexagon.L2.loadrb.pci
|
||||
unsigned char test2(int mod, void *start) {
|
||||
char *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrb_pci(&base, 4, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test3
|
||||
// CHECK: @llvm.hexagon.L2.loadruh.pci
|
||||
unsigned short test3(int mod, void *start) {
|
||||
unsigned short *base = start;
|
||||
return __builtin_HEXAGON_L2_loadruh_pci(&base, 4, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test4
|
||||
// CHECK: @llvm.hexagon.L2.loadrh.pci
|
||||
short test4(int mod, void *start) {
|
||||
short *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrh_pci(&base, 4, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test5
|
||||
// CHECK: @llvm.hexagon.L2.loadri.pci
|
||||
int test5(int mod, void *start) {
|
||||
int *base = start;
|
||||
return __builtin_HEXAGON_L2_loadri_pci(&base, 4, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test6
|
||||
// CHECK: @llvm.hexagon.L2.loadrd.pci
|
||||
long long test6(int mod, void *start) {
|
||||
long long *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrd_pci(&base, 8, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test7
|
||||
// CHECK: @llvm.hexagon.L2.loadrub.pcr
|
||||
unsigned char test7(int mod, void *start) {
|
||||
unsigned char *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrub_pcr(&base, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test8
|
||||
// CHECK: @llvm.hexagon.L2.loadrb.pcr
|
||||
unsigned char test8(int mod, void *start) {
|
||||
char *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrb_pcr(&base, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test9
|
||||
// CHECK: @llvm.hexagon.L2.loadruh.pcr
|
||||
unsigned short test9(int mod, void *start) {
|
||||
unsigned short *base = start;
|
||||
return __builtin_HEXAGON_L2_loadruh_pcr(&base, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test10
|
||||
// CHECK: @llvm.hexagon.L2.loadrh.pcr
|
||||
short test10(int mod, void *start) {
|
||||
short *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrh_pcr(&base, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test11
|
||||
// CHECK: @llvm.hexagon.L2.loadri.pcr
|
||||
int test11(int mod, void *start) {
|
||||
int *base = start;
|
||||
return __builtin_HEXAGON_L2_loadri_pcr(&base, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test12
|
||||
// CHECK: @llvm.hexagon.L2.loadrd.pcr
|
||||
long long test12(int mod, void *start) {
|
||||
long long *base = start;
|
||||
return __builtin_HEXAGON_L2_loadrd_pcr(&base, mod, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test13
|
||||
// CHECK: @llvm.hexagon.S2.storerb.pci
|
||||
void test13(int mod, void *start, char v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerb_pci(&base, 4, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test14
|
||||
// CHECK: @llvm.hexagon.S2.storerh.pci
|
||||
void test14(int mod, void *start, short v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerh_pci(&base, 4, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test15
|
||||
// CHECK: @llvm.hexagon.S2.storerf.pci
|
||||
void test15(int mod, void *start, short v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerf_pci(&base, 4, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test16
|
||||
// CHECK: @llvm.hexagon.S2.storeri.pci
|
||||
void test16(int mod, void *start, int v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storeri_pci(&base, 4, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test17
|
||||
// CHECK: @llvm.hexagon.S2.storerd.pci
|
||||
void test17(int mod, void *start, long long v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerd_pci(&base, 8, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test18
|
||||
// CHECK: @llvm.hexagon.S2.storerb.pcr
|
||||
void test18(int mod, void *start, char v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerb_pcr(&base, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test19
|
||||
// CHECK: @llvm.hexagon.S2.storerh.pcr
|
||||
void test19(int mod, void *start, short v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerh_pcr(&base, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test20
|
||||
// CHECK: @llvm.hexagon.S2.storerf.pcr
|
||||
void test20(int mod, void *start, short v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerf_pcr(&base, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test21
|
||||
// CHECK: @llvm.hexagon.S2.storeri.pcr
|
||||
void test21(int mod, void *start, int v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storeri_pcr(&base, mod, v, start);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test22
|
||||
// CHECK: @llvm.hexagon.S2.storerd.pcr
|
||||
void test22(int mod, void *start, long long v) {
|
||||
void *base = start;
|
||||
__builtin_HEXAGON_S2_storerd_pcr(&base, mod, v, start);
|
||||
}
|
Loading…
Reference in New Issue