Skip to content
Permalink
Browse files
8259536: Add cast nodes between interger types implementation for Arm…
… SVE

Reviewed-by: njian, xgong
  • Loading branch information
Wang Huang authored and Ningsheng Jian committed Feb 3, 2021
1 parent 6381e8d commit f53ee78bd0521b0dd03f9423da2f3f6dcad9436d
Showing with 346 additions and 14 deletions.
  1. +202 −7 src/hotspot/cpu/aarch64/aarch64_sve.ad
  2. +143 −7 src/hotspot/cpu/aarch64/aarch64_sve_ad.m4
  3. +1 −0 src/hotspot/share/opto/vectorIntrinsics.cpp
@@ -1,6 +1,6 @@
//
// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2020, Arm Limited. All rights reserved.
// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2020, 2021, Arm Limited. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
@@ -233,13 +233,8 @@ source %{
// Vector API specific
case Op_LoadVectorGather:
case Op_StoreVectorScatter:
case Op_VectorCast:
case Op_VectorCastB2X:
case Op_VectorCastD2X:
case Op_VectorCastF2X:
case Op_VectorCastI2X:
case Op_VectorCastL2X:
case Op_VectorCastS2X:
case Op_VectorInsert:
case Op_VectorLoadConst:
case Op_VectorLoadShuffle:
@@ -2489,3 +2484,203 @@ instruct vsubD(vReg dst, vReg src1, vReg src2) %{
ins_pipe(pipe_slow);
%}

// ------------------------------ Vector cast -------------------------------

instruct vcvtBtoS(vReg dst, vReg src)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
match(Set dst (VectorCastB2X src));
ins_cost(SVE_COST);
format %{ "sve_sunpklo $dst, H, $src\t# convert B to S vector" %}
ins_encode %{
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg));
%}
ins_pipe(pipe_slow);
%}

instruct vcvtStoI(vReg dst, vReg src)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_INT);
match(Set dst (VectorCastS2X src));
ins_cost(SVE_COST);
format %{ "sve_sunpklo $dst, S, $src\t# convert S to I vector" %}
ins_encode %{
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg));
%}
ins_pipe(pipe_slow);
%}

instruct vcvtItoL(vReg dst, vReg src)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_LONG);
match(Set dst (VectorCastI2X src));
ins_cost(SVE_COST);
format %{ "sve_sunpklo $dst, D, $src\t# convert I to L vector" %}
ins_encode %{
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg));
%}
ins_pipe(pipe_slow);
%}


instruct vcvtBtoI(vReg dst, vReg src)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_INT);
match(Set dst (VectorCastB2X src));
effect(TEMP_DEF dst);
ins_cost(2 * SVE_COST);
format %{ "sve_sunpklo $dst, H, $src\n\t"
"sve_sunpklo $dst, S, $dst\t# convert B to I vector" %}
ins_encode %{
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg));
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($dst$$reg));
%}
ins_pipe(pipe_slow);
%}

instruct vcvtStoL(vReg dst, vReg src)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_LONG);
match(Set dst (VectorCastS2X src));
effect(TEMP_DEF dst);
ins_cost(2 * SVE_COST);
format %{ "sve_sunpklo $dst, S, $src\n\t"
"sve_sunpklo $dst, D, $dst\t# convert S to L vector" %}
ins_encode %{
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg));
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($dst$$reg));
%}
ins_pipe(pipe_slow);
%}


instruct vcvtBtoL(vReg dst, vReg src)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_LONG);
match(Set dst (VectorCastB2X src));
effect(TEMP_DEF dst);
ins_cost(3 * SVE_COST);
format %{ "sve_sunpklo $dst, H, $src\n\t"
"sve_sunpklo $dst, S, $dst\n\t"
"sve_sunpklo $dst, D, $dst\t# convert B to L vector" %}
ins_encode %{
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg));
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($dst$$reg));
__ sve_sunpklo(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($dst$$reg));
%}
ins_pipe(pipe_slow);
%}


instruct vcvtStoB(vReg dst, vReg src, vReg tmp)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
match(Set dst (VectorCastS2X src));
effect(TEMP tmp);
ins_cost(2 * SVE_COST);
format %{ "sve_dup $tmp, B, 0\n\t"
"sve_uzp1 $dst, B, $src, tmp\t# convert S to B vector" %}
ins_encode %{
__ sve_dup(as_FloatRegister($tmp$$reg), __ B, 0);
__ sve_uzp1(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_slow);
%}

instruct vcvtItoS(vReg dst, vReg src, vReg tmp)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
match(Set dst (VectorCastI2X src));
effect(TEMP tmp);
ins_cost(2 * SVE_COST);
format %{ "sve_dup $tmp, H, 0\n\t"
"sve_uzp1 $dst, H, $src, tmp\t# convert I to S vector" %}
ins_encode %{
__ sve_dup(as_FloatRegister($tmp$$reg), __ H, 0);
__ sve_uzp1(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_slow);
%}

instruct vcvtLtoI(vReg dst, vReg src, vReg tmp)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_INT);
match(Set dst (VectorCastL2X src));
effect(TEMP tmp);
ins_cost(2 * SVE_COST);
format %{ "sve_dup $tmp, S, 0\n\t"
"sve_uzp1 $dst, S, $src, tmp\t# convert L to I vector" %}
ins_encode %{
__ sve_dup(as_FloatRegister($tmp$$reg), __ S, 0);
__ sve_uzp1(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_slow);
%}


instruct vcvtItoB(vReg dst, vReg src, vReg tmp)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
match(Set dst (VectorCastI2X src));
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(3 * SVE_COST);
format %{ "sve_dup $tmp, H, 0\n\t"
"sve_uzp1 $dst, H, $src, tmp\n\t"
"sve_uzp1 $dst, B, $dst, tmp\n\t# convert I to B vector" %}
ins_encode %{
__ sve_dup(as_FloatRegister($tmp$$reg), __ H, 0);
__ sve_uzp1(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg));
__ sve_uzp1(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_slow);
%}

instruct vcvtLtoS(vReg dst, vReg src, vReg tmp)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
match(Set dst (VectorCastL2X src));
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(3 * SVE_COST);
format %{ "sve_dup $tmp, S, 0\n\t"
"sve_uzp1 $dst, S, $src, tmp\n\t"
"sve_uzp1 $dst, H, $dst, tmp\n\t# convert L to S vector" %}
ins_encode %{
__ sve_dup(as_FloatRegister($tmp$$reg), __ S, 0);
__ sve_uzp1(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg));
__ sve_uzp1(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_slow);
%}


instruct vcvtLtoB(vReg dst, vReg src, vReg tmp)
%{
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
match(Set dst (VectorCastL2X src));
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(4 * SVE_COST);
format %{ "sve_dup $tmp, S, 0\n\t"
"sve_uzp1 $dst, S, $src, tmp\n\t"
"sve_uzp1 $dst, H, $dst, tmp\n\t"
"sve_uzp1 $dst, B, $dst, tmp\n\t# convert L to B vector" %}
ins_encode %{
__ sve_dup(as_FloatRegister($tmp$$reg), __ S, 0);
__ sve_uzp1(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg));
__ sve_uzp1(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
__ sve_uzp1(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg));
%}
ins_pipe(pipe_slow);
%}

Loading

0 comments on commit f53ee78

Please sign in to comment.