Skip to content

Commit 32febe6

Browse files
Himadhithhimadhithtonykuttai
authored
[PowerPC] Support for Packed BCD conversion builtins (#142723)
Support the following packed BCD builtins for PowerPC. ``` __builtin_national2packed - Conversion of National format to Packed decimal format. __builtin_packed2national - Conversion of Packed decimal format to national format. __builtin_packed2zoned - Conversion of Packed decimal format to Zoned decimal format. __builtin_zoned2packed - Conversion of Zoned decimal format to Packed decimal format. ``` ### Prototypes: `vector unsigned char __builtin_national2packed(vector unsigned char a, unsigned char b);` `vector unsigned char __builtin_packed2zoned(vector unsigned char, unsigned char);` `vector unsigned char __builtin_zoned2packed(vector unsigned char, unsigned char);` The condition for the 2nd parameter is consistent over all the 3 prototypes (0 or 1 only). `vector unsigned char __builtin_packed2national(vector unsigned char);` Co-authored-by: himadhith <himadhith.v@ibm.com> Co-authored-by: Tony Varghese <tonypalampalliyil@gmail.com>
1 parent 0f01cd5 commit 32febe6

File tree

8 files changed

+232
-4
lines changed

8 files changed

+232
-4
lines changed

clang/include/clang/Basic/BuiltinsPPC.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,12 @@ TARGET_BUILTIN(__builtin_ppc_bcdadd_p, "iiV16UcV16Uc", "",
535535
TARGET_BUILTIN(__builtin_ppc_bcdsub_p, "iiV16UcV16Uc", "",
536536
"isa-v207-instructions")
537537

538+
// P9 Binary-coded decimal (BCD) builtins.
539+
TARGET_BUILTIN(__builtin_ppc_national2packed, "V16UcV16UcUc", "t", "power9-vector")
540+
TARGET_BUILTIN(__builtin_ppc_packed2national, "V16UcV16Uc", "", "power9-vector")
541+
TARGET_BUILTIN(__builtin_ppc_packed2zoned, "V16UcV16UcUc", "t", "power9-vector")
542+
TARGET_BUILTIN(__builtin_ppc_zoned2packed, "V16UcV16UcUc", "t", "power9-vector")
543+
538544
TARGET_BUILTIN(__builtin_altivec_vclzlsbb, "SiV16Uc", "", "power9-vector")
539545
TARGET_BUILTIN(__builtin_altivec_vctzlsbb, "SiV16Uc", "", "power9-vector")
540546
TARGET_BUILTIN(__builtin_altivec_vprtybw, "V4UiV4Ui", "", "power9-vector")

clang/lib/Basic/Targets/PPC.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
8989
}
9090

9191
static void defineXLCompatMacros(MacroBuilder &Builder) {
92+
Builder.defineMacro("__builtin_national2packed",
93+
"__builtin_ppc_national2packed");
94+
Builder.defineMacro("__builtin_packed2national",
95+
"__builtin_ppc_packed2national");
96+
Builder.defineMacro("__builtin_packed2zoned", "__builtin_ppc_packed2zoned");
97+
Builder.defineMacro("__builtin_zoned2packed", "__builtin_ppc_zoned2packed");
9298
Builder.defineMacro("__cdtbcd", "__builtin_ppc_cdtbcd");
9399
Builder.defineMacro("__cbcdtd", "__builtin_ppc_cbcdtd");
94100
Builder.defineMacro("__addg6s", "__builtin_ppc_addg6s");

clang/lib/Sema/SemaPPC.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
106106
switch (BuiltinID) {
107107
default:
108108
return false;
109+
case PPC::BI__builtin_ppc_national2packed:
110+
case PPC::BI__builtin_ppc_packed2zoned:
111+
case PPC::BI__builtin_ppc_zoned2packed:
112+
return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
109113
case PPC::BI__builtin_altivec_crypto_vshasigmaw:
110114
case PPC::BI__builtin_altivec_crypto_vshasigmad:
111115
return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
// Testfile that verifies positive cases (0 or 1 only) for BCD builtins national2packed, packed2zoned and zoned2packed.
3+
// REQUIRES: powerpc-registered-target
4+
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -O2 -target-cpu pwr9 \
5+
// RUN: -emit-llvm %s -o - | FileCheck %s
6+
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -O2 -target-cpu pwr9 \
7+
// RUN: -emit-llvm %s -o - | FileCheck %s
8+
// RUN: %clang_cc1 -triple powerpc-unknown-unknown -O2 -target-cpu pwr9 \
9+
// RUN: -emit-llvm %s -o - | FileCheck %s
10+
11+
// CHECK-LABEL: define dso_local <16 x i8> @tBcd_National2packed_imm1(
12+
// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
13+
// CHECK-NEXT: [[ENTRY:.*:]]
14+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> [[A]], i32 1)
15+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
16+
//
17+
vector unsigned char tBcd_National2packed_imm1(vector unsigned char a) {
18+
return __builtin_ppc_national2packed (a,'\1');
19+
}
20+
21+
// CHECK-LABEL: define dso_local <16 x i8> @tBcd_National2packed_imm0(
22+
// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
23+
// CHECK-NEXT: [[ENTRY:.*:]]
24+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> [[A]], i32 0)
25+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
26+
//
27+
vector unsigned char tBcd_National2packed_imm0(vector unsigned char a) {
28+
return __builtin_ppc_national2packed (a,'\0');
29+
}
30+
31+
// CHECK-LABEL: define dso_local <16 x i8> @tBcd_Packed2national(
32+
// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
33+
// CHECK-NEXT: [[ENTRY:.*:]]
34+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2national(<16 x i8> [[A]])
35+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
36+
//
37+
vector unsigned char tBcd_Packed2national(vector unsigned char a){
38+
return __builtin_ppc_packed2national(a);
39+
}
40+
41+
// CHECK-LABEL: define dso_local <16 x i8> @tBcd_Packed2zoned_imm0(
42+
// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
43+
// CHECK-NEXT: [[ENTRY:.*:]]
44+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> [[A]], i32 0)
45+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
46+
//
47+
vector unsigned char tBcd_Packed2zoned_imm0(vector unsigned char a){
48+
return __builtin_ppc_packed2zoned(a,'\0');
49+
}
50+
51+
// CHECK-LABEL: define dso_local <16 x i8> @tBcd_Packed2zoned_imm1(
52+
// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
53+
// CHECK-NEXT: [[ENTRY:.*:]]
54+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> [[A]], i32 1)
55+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
56+
//
57+
vector unsigned char tBcd_Packed2zoned_imm1(vector unsigned char a){
58+
return __builtin_ppc_packed2zoned(a,'\1');
59+
}
60+
61+
// CHECK-LABEL: define dso_local <16 x i8> @tBcd_Zoned2packed_imm0(
62+
// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
63+
// CHECK-NEXT: [[ENTRY:.*:]]
64+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> [[A]], i32 0)
65+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
66+
//
67+
vector unsigned char tBcd_Zoned2packed_imm0(vector unsigned char a){
68+
return __builtin_ppc_zoned2packed(a,'\0');
69+
}
70+
71+
// CHECK-LABEL: define dso_local <16 x i8> @tBcd_Zoned2packed_imm1(
72+
// CHECK-SAME: <16 x i8> noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
73+
// CHECK-NEXT: [[ENTRY:.*:]]
74+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> [[A]], i32 1)
75+
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
76+
//
77+
vector unsigned char tBcd_Zoned2packed_imm1(vector unsigned char a){
78+
return __builtin_ppc_zoned2packed(a,'\1');
79+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Testfile to verify the semantics and the error handling for BCD builtins national2packed, packed2zoned and zoned2packed.
2+
// REQUIRES: powerpc-registered-target
3+
// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64-unknown-unknown -fsyntax-only -verify %s
4+
// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64le-unknown-unknown -fsyntax-only -verify %s
5+
// RUN: %clang_cc1 -target-feature +altivec -triple powerpc-unknown-unknown -fsyntax-only -verify %s
6+
7+
#include <altivec.h>
8+
vector unsigned char test_national2packed(void)
9+
{
10+
vector unsigned char a = {1,2,3,4};
11+
vector unsigned char res_a = __builtin_ppc_national2packed(a, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
12+
vector unsigned char res_b = __builtin_ppc_national2packed(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
13+
return __builtin_ppc_national2packed(a, 0);
14+
}
15+
16+
vector unsigned char test_packed2zoned(void)
17+
{
18+
vector unsigned char a = {1,2,3,4};
19+
vector unsigned char res_a = __builtin_ppc_packed2zoned(a,2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
20+
vector unsigned char res_b = __builtin_ppc_packed2zoned(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
21+
return __builtin_ppc_packed2zoned(a,1);
22+
}
23+
24+
vector unsigned char test_zoned2packed(void)
25+
{
26+
vector unsigned char a = {1,2,3,4};
27+
vector unsigned char res_a = __builtin_ppc_zoned2packed(a,2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
28+
vector unsigned char res_b = __builtin_ppc_zoned2packed(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
29+
return __builtin_ppc_zoned2packed(a,0);
30+
}

llvm/include/llvm/IR/IntrinsicsPowerPC.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,14 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
655655
DefaultAttrsIntrinsic<[llvm_v1i128_ty],[llvm_v1i128_ty],[IntrNoMem]>;
656656

657657
// BCD intrinsics.
658+
def int_ppc_national2packed: ClangBuiltin<"__builtin_ppc_national2packed">,
659+
DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
660+
def int_ppc_packed2national: ClangBuiltin<"__builtin_ppc_packed2national">,
661+
DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty], [IntrNoMem]>;
662+
def int_ppc_packed2zoned: ClangBuiltin<"__builtin_ppc_packed2zoned">,
663+
DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
664+
def int_ppc_zoned2packed: ClangBuiltin<"__builtin_ppc_zoned2packed">,
665+
DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
658666
def int_ppc_cdtbcdd : ClangBuiltin<"__builtin_ppc_cdtbcd">,
659667
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
660668
def int_ppc_cbcdtdd: ClangBuiltin<"__builtin_ppc_cbcdtd">,

llvm/lib/Target/PowerPC/PPCInstrAltivec.td

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,10 +1617,14 @@ class VX_VT5_EO5_VB5_XO9_o<bits<5> eo, bits<9> xo, string opc,
16171617
}
16181618

16191619
// Decimal Convert From/to National/Zoned/Signed-QWord
1620-
def BCDCFN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<7, 385, "bcdcfn." , []>;
1621-
def BCDCFZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<6, 385, "bcdcfz." , []>;
1622-
def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." , []>;
1623-
def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." , []>;
1620+
def BCDCFN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<7, 385, "bcdcfn." ,
1621+
[(set v16i8:$VD, (int_ppc_national2packed v16i8:$VB, timm:$PS))]>;
1622+
def BCDCFZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<6, 385, "bcdcfz." ,
1623+
[(set v16i8:$VD, (int_ppc_zoned2packed v16i8:$VB, timm:$PS))]>;
1624+
def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." ,
1625+
[(set v16i8:$VD, (int_ppc_packed2national v16i8:$VB))]>;
1626+
def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." ,
1627+
[(set v16i8:$VD, (int_ppc_packed2zoned v16i8:$VB, timm:$PS))]>;
16241628
def BCDCFSQ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<2, 385, "bcdcfsq.", []>;
16251629
def BCDCTSQ_rec : VX_VT5_EO5_VB5_XO9_o <0, 385, "bcdctsq.", []>;
16261630

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; Testfile that verifies positive case (0 or 1 only) for BCD builtins national2packed, packed2zoned and zoned2packed.
3+
; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \
4+
; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
5+
6+
; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64-unknown-unknown \
7+
; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
8+
9+
; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc-unknown-unknown \
10+
; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
11+
12+
; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64-ibm-aix-xcoff \
13+
; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
14+
15+
declare <16 x i8> @llvm.ppc.national2packed(<16 x i8>, i32 immarg)
16+
17+
define <16 x i8> @tBcd_National2packed_imm0(<16 x i8> %a) {
18+
; CHECK-LABEL: tBcd_National2packed_imm0:
19+
; CHECK: # %bb.0: # %entry
20+
; CHECK-NEXT: bcdcfn. v2, v2, 0
21+
; CHECK-NEXT: blr
22+
entry:
23+
%0 = call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 0)
24+
ret <16 x i8> %0
25+
}
26+
27+
define <16 x i8> @tBcd_National2packed_imm1(<16 x i8> %a) {
28+
; CHECK-LABEL: tBcd_National2packed_imm1:
29+
; CHECK: # %bb.0: # %entry
30+
; CHECK-NEXT: bcdcfn. v2, v2, 1
31+
; CHECK-NEXT: blr
32+
entry:
33+
%0 = call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 1)
34+
ret <16 x i8> %0
35+
}
36+
37+
declare <16 x i8> @llvm.ppc.packed2national(<16 x i8>)
38+
39+
define <16 x i8> @tBcd_Packed2national(<16 x i8> %a) {
40+
; CHECK-LABEL: tBcd_Packed2national:
41+
; CHECK: # %bb.0: # %entry
42+
; CHECK-NEXT: bcdctn. v2, v2
43+
; CHECK-NEXT: blr
44+
entry:
45+
%0 = call <16 x i8> @llvm.ppc.packed2national(<16 x i8> %a)
46+
ret <16 x i8> %0
47+
}
48+
49+
declare <16 x i8> @llvm.ppc.packed2zoned(<16 x i8>, i32 immarg)
50+
51+
define <16 x i8> @tBcd_Packed2zoned_imm0(<16 x i8> %a) {
52+
; CHECK-LABEL: tBcd_Packed2zoned_imm0:
53+
; CHECK: # %bb.0: # %entry
54+
; CHECK-NEXT: bcdctz. v2, v2, 0
55+
; CHECK-NEXT: blr
56+
entry:
57+
%0 = call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 0)
58+
ret <16 x i8> %0
59+
}
60+
61+
define <16 x i8> @tBcd_Packed2zoned_imm1(<16 x i8> %a) {
62+
; CHECK-LABEL: tBcd_Packed2zoned_imm1:
63+
; CHECK: # %bb.0: # %entry
64+
; CHECK-NEXT: bcdctz. v2, v2, 1
65+
; CHECK-NEXT: blr
66+
entry:
67+
%0 = call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 1)
68+
ret <16 x i8> %0
69+
}
70+
71+
declare <16 x i8> @llvm.ppc.zoned2packed(<16 x i8>, i32 immarg)
72+
73+
define <16 x i8> @tBcd_Zoned2packed_imm0(<16 x i8> %a) {
74+
; CHECK-LABEL: tBcd_Zoned2packed_imm0:
75+
; CHECK: # %bb.0: # %entry
76+
; CHECK-NEXT: bcdcfz. v2, v2, 0
77+
; CHECK-NEXT: blr
78+
entry:
79+
%0 = call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 0)
80+
ret <16 x i8> %0
81+
}
82+
83+
define <16 x i8> @tBcd_Zoned2packed_imm1(<16 x i8> %a) {
84+
; CHECK-LABEL: tBcd_Zoned2packed_imm1:
85+
; CHECK: # %bb.0: # %entry
86+
; CHECK-NEXT: bcdcfz. v2, v2, 1
87+
; CHECK-NEXT: blr
88+
entry:
89+
%0 = call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 1)
90+
ret <16 x i8> %0
91+
}

0 commit comments

Comments
 (0)