Skip to content

Commit 8193800

Browse files
Fei GaoNingsheng Jian
authored andcommitted
8274179: AArch64: Support SVE operations with encodable immediates
Reviewed-by: aph, ngasson
1 parent b8453eb commit 8193800

File tree

12 files changed

+1433
-147
lines changed

12 files changed

+1433
-147
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,12 +2685,55 @@ bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
26852685
return true;
26862686
}
26872687

2688+
bool can_combine_with_imm(Node* binary_node, Node* replicate_node) {
2689+
if (UseSVE == 0 || !VectorNode::is_invariant_vector(replicate_node)){
2690+
return false;
2691+
}
2692+
Node* imm_node = replicate_node->in(1);
2693+
if (!imm_node->is_Con()) {
2694+
return false;
2695+
}
2696+
2697+
const Type* t = imm_node->bottom_type();
2698+
if (!(t->isa_int() || t->isa_long())) {
2699+
return false;
2700+
}
2701+
2702+
switch (binary_node->Opcode()) {
2703+
case Op_AndV:
2704+
case Op_OrV:
2705+
case Op_XorV: {
2706+
Assembler::SIMD_RegVariant T = Assembler::elemType_to_regVariant(Matcher::vector_element_basic_type(binary_node));
2707+
uint64_t value = t->isa_long() ? (uint64_t)imm_node->get_long() : (uint64_t)imm_node->get_int();
2708+
return Assembler::operand_valid_for_sve_logical_immediate(Assembler::regVariant_to_elemBits(T), value);
2709+
}
2710+
case Op_AddVB:
2711+
return (imm_node->get_int() <= 255 && imm_node->get_int() >= -255);
2712+
case Op_AddVS:
2713+
case Op_AddVI:
2714+
return Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)imm_node->get_int());
2715+
case Op_AddVL:
2716+
return Assembler::operand_valid_for_sve_add_sub_immediate(imm_node->get_long());
2717+
default:
2718+
return false;
2719+
}
2720+
}
2721+
2722+
bool is_vector_arith_imm_pattern(Node* n, Node* m) {
2723+
if (n != NULL && m != NULL) {
2724+
return can_combine_with_imm(n, m);
2725+
}
2726+
return false;
2727+
}
2728+
26882729
// Should the matcher clone input 'm' of node 'n'?
26892730
bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
26902731
// ShiftV src (ShiftCntV con)
26912732
// StoreVector (VectorStoreMask src)
2733+
// Binary src (Replicate con)
26922734
if (is_vshift_con_pattern(n, m) ||
2693-
(UseSVE > 0 && m->Opcode() == Op_VectorStoreMask && n->Opcode() == Op_StoreVector)) {
2735+
(UseSVE > 0 && m->Opcode() == Op_VectorStoreMask && n->Opcode() == Op_StoreVector) ||
2736+
is_vector_arith_imm_pattern(n, m)) {
26942737
mstack.push(m, Visit);
26952738
return true;
26962739
}
@@ -4611,6 +4654,17 @@ operand immL8_shift8()
46114654
interface(CONST_INTER);
46124655
%}
46134656

4657+
// 8 bit integer valid for vector add sub immediate
4658+
operand immBAddSubV()
4659+
%{
4660+
predicate(n->get_int() <= 255 && n->get_int() >= -255);
4661+
match(ConI);
4662+
4663+
op_cost(0);
4664+
format %{ %}
4665+
interface(CONST_INTER);
4666+
%}
4667+
46144668
// 32 bit integer valid for add sub immediate
46154669
operand immIAddSub()
46164670
%{
@@ -4621,8 +4675,39 @@ operand immIAddSub()
46214675
interface(CONST_INTER);
46224676
%}
46234677

4678+
// 32 bit integer valid for vector add sub immediate
4679+
operand immIAddSubV()
4680+
%{
4681+
predicate(Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)n->get_int()));
4682+
match(ConI);
4683+
4684+
op_cost(0);
4685+
format %{ %}
4686+
interface(CONST_INTER);
4687+
%}
4688+
46244689
// 32 bit unsigned integer valid for logical immediate
4625-
// TODO -- check this is right when e.g the mask is 0x80000000
4690+
4691+
operand immBLog()
4692+
%{
4693+
predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerByte, (uint64_t)n->get_int()));
4694+
match(ConI);
4695+
4696+
op_cost(0);
4697+
format %{ %}
4698+
interface(CONST_INTER);
4699+
%}
4700+
4701+
operand immSLog()
4702+
%{
4703+
predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerShort, (uint64_t)n->get_int()));
4704+
match(ConI);
4705+
4706+
op_cost(0);
4707+
format %{ %}
4708+
interface(CONST_INTER);
4709+
%}
4710+
46264711
operand immILog()
46274712
%{
46284713
predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int()));
@@ -4700,6 +4785,17 @@ operand immLAddSub()
47004785
interface(CONST_INTER);
47014786
%}
47024787

4788+
// 64 bit integer valid for addv subv immediate
4789+
operand immLAddSubV()
4790+
%{
4791+
predicate(Assembler::operand_valid_for_sve_add_sub_immediate(n->get_long()));
4792+
match(ConL);
4793+
4794+
op_cost(0);
4795+
format %{ %}
4796+
interface(CONST_INTER);
4797+
%}
4798+
47034799
// 64 bit integer valid for logical immediate
47044800
operand immLLog()
47054801
%{

src/hotspot/cpu/aarch64/aarch64_sve.ad

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,217 @@ instruct vaddD_masked(vReg dst_src1, vReg src2, pRegGov pg) %{
935935
ins_pipe(pipe_slow);
936936
%}
937937

938+
// vector add reg imm (unpredicated)
939+
940+
instruct vaddImmB(vReg dst_src, immBAddSubV con) %{
941+
predicate(UseSVE > 0);
942+
match(Set dst_src (AddVB dst_src (ReplicateB con)));
943+
ins_cost(SVE_COST);
944+
format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (B)" %}
945+
ins_encode %{
946+
int32_t val = $con$$constant;
947+
if (val > 0){
948+
__ sve_add(as_FloatRegister($dst_src$$reg), __ B, val);
949+
} else if (val < 0){
950+
__ sve_sub(as_FloatRegister($dst_src$$reg), __ B, -val);
951+
}
952+
%}
953+
ins_pipe(pipe_slow);
954+
%}
955+
956+
instruct vaddImmS(vReg dst_src, immIAddSubV con) %{
957+
predicate(UseSVE > 0);
958+
match(Set dst_src (AddVS dst_src (ReplicateS con)));
959+
ins_cost(SVE_COST);
960+
format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (H)" %}
961+
ins_encode %{
962+
int32_t val = $con$$constant;
963+
if (val > 0){
964+
__ sve_add(as_FloatRegister($dst_src$$reg), __ H, val);
965+
} else if (val < 0){
966+
__ sve_sub(as_FloatRegister($dst_src$$reg), __ H, -val);
967+
}
968+
%}
969+
ins_pipe(pipe_slow);
970+
%}
971+
972+
instruct vaddImmI(vReg dst_src, immIAddSubV con) %{
973+
predicate(UseSVE > 0);
974+
match(Set dst_src (AddVI dst_src (ReplicateI con)));
975+
ins_cost(SVE_COST);
976+
format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (S)" %}
977+
ins_encode %{
978+
int32_t val = $con$$constant;
979+
if (val > 0){
980+
__ sve_add(as_FloatRegister($dst_src$$reg), __ S, val);
981+
} else if (val < 0){
982+
__ sve_sub(as_FloatRegister($dst_src$$reg), __ S, -val);
983+
}
984+
%}
985+
ins_pipe(pipe_slow);
986+
%}
987+
988+
instruct vaddImmL(vReg dst_src, immLAddSubV con) %{
989+
predicate(UseSVE > 0);
990+
match(Set dst_src (AddVL dst_src (ReplicateL con)));
991+
ins_cost(SVE_COST);
992+
format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (D)" %}
993+
ins_encode %{
994+
int32_t val = $con$$constant;
995+
if (val > 0){
996+
__ sve_add(as_FloatRegister($dst_src$$reg), __ D, val);
997+
} else if (val < 0){
998+
__ sve_sub(as_FloatRegister($dst_src$$reg), __ D, -val);
999+
}
1000+
%}
1001+
ins_pipe(pipe_slow);
1002+
%}
1003+
1004+
// vector binary op reg imm (unpredicated)
1005+
1006+
instruct vandB(vReg dst_src, immBLog con) %{
1007+
predicate(UseSVE > 0);
1008+
match(Set dst_src (AndV dst_src (ReplicateB con)));
1009+
ins_cost(SVE_COST);
1010+
format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (B)" %}
1011+
ins_encode %{
1012+
__ sve_and(as_FloatRegister($dst_src$$reg), __ B,
1013+
(uint64_t)($con$$constant));
1014+
%}
1015+
ins_pipe(pipe_slow);
1016+
%}
1017+
1018+
instruct vandH(vReg dst_src, immSLog con) %{
1019+
predicate(UseSVE > 0);
1020+
match(Set dst_src (AndV dst_src (ReplicateS con)));
1021+
ins_cost(SVE_COST);
1022+
format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (H)" %}
1023+
ins_encode %{
1024+
__ sve_and(as_FloatRegister($dst_src$$reg), __ H,
1025+
(uint64_t)($con$$constant));
1026+
%}
1027+
ins_pipe(pipe_slow);
1028+
%}
1029+
1030+
instruct vandS(vReg dst_src, immILog con) %{
1031+
predicate(UseSVE > 0);
1032+
match(Set dst_src (AndV dst_src (ReplicateI con)));
1033+
ins_cost(SVE_COST);
1034+
format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (S)" %}
1035+
ins_encode %{
1036+
__ sve_and(as_FloatRegister($dst_src$$reg), __ S,
1037+
(uint64_t)($con$$constant));
1038+
%}
1039+
ins_pipe(pipe_slow);
1040+
%}
1041+
1042+
instruct vandD(vReg dst_src, immLLog con) %{
1043+
predicate(UseSVE > 0);
1044+
match(Set dst_src (AndV dst_src (ReplicateL con)));
1045+
ins_cost(SVE_COST);
1046+
format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (D)" %}
1047+
ins_encode %{
1048+
__ sve_and(as_FloatRegister($dst_src$$reg), __ D,
1049+
(uint64_t)($con$$constant));
1050+
%}
1051+
ins_pipe(pipe_slow);
1052+
%}
1053+
1054+
instruct vorB(vReg dst_src, immBLog con) %{
1055+
predicate(UseSVE > 0);
1056+
match(Set dst_src (OrV dst_src (ReplicateB con)));
1057+
ins_cost(SVE_COST);
1058+
format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (B)" %}
1059+
ins_encode %{
1060+
__ sve_orr(as_FloatRegister($dst_src$$reg), __ B,
1061+
(uint64_t)($con$$constant));
1062+
%}
1063+
ins_pipe(pipe_slow);
1064+
%}
1065+
1066+
instruct vorH(vReg dst_src, immSLog con) %{
1067+
predicate(UseSVE > 0);
1068+
match(Set dst_src (OrV dst_src (ReplicateS con)));
1069+
ins_cost(SVE_COST);
1070+
format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (H)" %}
1071+
ins_encode %{
1072+
__ sve_orr(as_FloatRegister($dst_src$$reg), __ H,
1073+
(uint64_t)($con$$constant));
1074+
%}
1075+
ins_pipe(pipe_slow);
1076+
%}
1077+
1078+
instruct vorS(vReg dst_src, immILog con) %{
1079+
predicate(UseSVE > 0);
1080+
match(Set dst_src (OrV dst_src (ReplicateI con)));
1081+
ins_cost(SVE_COST);
1082+
format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (S)" %}
1083+
ins_encode %{
1084+
__ sve_orr(as_FloatRegister($dst_src$$reg), __ S,
1085+
(uint64_t)($con$$constant));
1086+
%}
1087+
ins_pipe(pipe_slow);
1088+
%}
1089+
1090+
instruct vorD(vReg dst_src, immLLog con) %{
1091+
predicate(UseSVE > 0);
1092+
match(Set dst_src (OrV dst_src (ReplicateL con)));
1093+
ins_cost(SVE_COST);
1094+
format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (D)" %}
1095+
ins_encode %{
1096+
__ sve_orr(as_FloatRegister($dst_src$$reg), __ D,
1097+
(uint64_t)($con$$constant));
1098+
%}
1099+
ins_pipe(pipe_slow);
1100+
%}
1101+
1102+
instruct vxorB(vReg dst_src, immBLog con) %{
1103+
predicate(UseSVE > 0);
1104+
match(Set dst_src (XorV dst_src (ReplicateB con)));
1105+
ins_cost(SVE_COST);
1106+
format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (B)" %}
1107+
ins_encode %{
1108+
__ sve_eor(as_FloatRegister($dst_src$$reg), __ B,
1109+
(uint64_t)($con$$constant));
1110+
%}
1111+
ins_pipe(pipe_slow);
1112+
%}
1113+
1114+
instruct vxorH(vReg dst_src, immSLog con) %{
1115+
predicate(UseSVE > 0);
1116+
match(Set dst_src (XorV dst_src (ReplicateS con)));
1117+
ins_cost(SVE_COST);
1118+
format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (H)" %}
1119+
ins_encode %{
1120+
__ sve_eor(as_FloatRegister($dst_src$$reg), __ H,
1121+
(uint64_t)($con$$constant));
1122+
%}
1123+
ins_pipe(pipe_slow);
1124+
%}
1125+
1126+
instruct vxorS(vReg dst_src, immILog con) %{
1127+
predicate(UseSVE > 0);
1128+
match(Set dst_src (XorV dst_src (ReplicateI con)));
1129+
ins_cost(SVE_COST);
1130+
format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (S)" %}
1131+
ins_encode %{
1132+
__ sve_eor(as_FloatRegister($dst_src$$reg), __ S,
1133+
(uint64_t)($con$$constant));
1134+
%}
1135+
ins_pipe(pipe_slow);
1136+
%}
1137+
1138+
instruct vxorD(vReg dst_src, immLLog con) %{
1139+
predicate(UseSVE > 0);
1140+
match(Set dst_src (XorV dst_src (ReplicateL con)));
1141+
ins_cost(SVE_COST);
1142+
format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (D)" %}
1143+
ins_encode %{
1144+
__ sve_eor(as_FloatRegister($dst_src$$reg), __ D,
1145+
(uint64_t)($con$$constant));
1146+
%}
1147+
ins_pipe(pipe_slow);
1148+
%}
9381149
// vector and
9391150

9401151
instruct vand(vReg dst, vReg src1, vReg src2) %{

0 commit comments

Comments
 (0)