diff options
author | Kong Lingling <lingling.kong@intel.com> | 2023-03-23 14:25:50 +0800 |
---|---|---|
committer | Hongyu Wang <hongyu.wang@intel.com> | 2023-10-07 16:34:30 +0800 |
commit | ccdc0f0fcf6f240d5c4f059e6f38547a0cca9723 (patch) | |
tree | 1db898c940cdf4ac3098671f612bde8826f15b48 /gcc | |
parent | 0793ee05b078b99c55170c14c4a32b94d3a54cab (diff) | |
download | gcc-ccdc0f0fcf6f240d5c4f059e6f38547a0cca9723.zip gcc-ccdc0f0fcf6f240d5c4f059e6f38547a0cca9723.tar.gz gcc-ccdc0f0fcf6f240d5c4f059e6f38547a0cca9723.tar.bz2 |
[APX EGPR] Map reg/mem constraints in inline asm to non-EGPR constraint.
In inline asm, we do not know if the insn can use EGPR, so disable EGPR
usage by default via mapping the common reg/mem constraint to non-EGPR
constraints.
The full list of mapping goes like
"g" -> "jrjmi"
"r" -> "jr"
"m" -> "jm"
"<" -> "j<"
">" -> "j>"
"o" -> "jo"
"V" -> "jV"
"p" -> "jp"
"Bm" -> "ja
For memory constraints, we add an option -mapx-inline-asm-use-gpr32
to allow/disallow gpr32 usage in any memory related constraints, as
base_reg_class/index_reg_class cannot aware whether the asm insn
support gpr32 or not.
gcc/ChangeLog:
* config/i386/i386.cc (map_egpr_constraints): New funciton to
map common constraints to EGPR prohibited constraints.
(ix86_md_asm_adjust): Calls map_egpr_constraints.
* config/i386/i386.opt: Add option mapx-inline-asm-use-gpr32.
gcc/testsuite/ChangeLog:
* gcc.target/i386/apx-inline-gpr-norex2.c: New test.
Co-authored-by: Hongyu Wang <hongyu.wang@intel.com>
Co-authored-by: Hongtao Liu <hongtao.liu@intel.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/i386.cc | 92 | ||||
-rw-r--r-- | gcc/config/i386/i386.opt | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/apx-inline-gpr-norex2.c | 25 |
3 files changed, 122 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index ada9ac8..a983513 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +#define INCLUDE_STRING #define IN_TARGET_CODE 1 #include "config.h" @@ -23168,6 +23169,93 @@ ix86_c_mode_for_suffix (char suffix) return VOIDmode; } +/* Helper function to map common constraints to non-EGPR ones. + All related constraints have h prefix, and h plus Upper letter + means the constraint is strictly EGPR enabled, while h plus + lower letter indicates the constraint is strictly gpr16 only. + + Specially for "g" constraint, split it to rmi as there is + no corresponding general constraint define for backend. + + Here is the full list to map constraints that may involve + gpr to h prefixed. + + "g" -> "jrjmi" + "r" -> "jr" + "m" -> "jm" + "<" -> "j<" + ">" -> "j>" + "o" -> "jo" + "V" -> "jV" + "p" -> "jp" + "Bm" -> "ja" +*/ + +static void map_egpr_constraints (vec<const char *> &constraints) +{ + for (size_t i = 0; i < constraints.length(); i++) + { + const char *cur = constraints[i]; + + if (startswith (cur, "=@cc")) + continue; + + int len = strlen (cur); + auto_vec<char> buf; + + for (int j = 0; j < len; j++) + { + switch (cur[j]) + { + case 'g': + buf.safe_push ('j'); + buf.safe_push ('r'); + buf.safe_push ('j'); + buf.safe_push ('m'); + buf.safe_push ('i'); + break; + case 'r': + case 'm': + case '<': + case '>': + case 'o': + case 'V': + case 'p': + buf.safe_push ('j'); + buf.safe_push (cur[j]); + break; + case 'B': + if (cur[j + 1] == 'm') + { + buf.safe_push ('j'); + buf.safe_push ('a'); + j++; + } + else + { + buf.safe_push (cur[j]); + buf.safe_push (cur[j + 1]); + j++; + } + break; + case 'T': + case 'Y': + case 'W': + case 'j': + buf.safe_push (cur[j]); + buf.safe_push (cur[j + 1]); + j++; + break; + default: + buf.safe_push (cur[j]); + break; + } + } + buf.safe_push ('\0'); + constraints[i] = xstrdup (buf.address ()); + } +} + /* Worker function for TARGET_MD_ASM_ADJUST. We implement asm flag outputs, and maintain source compatibility @@ -23182,6 +23270,10 @@ ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/, bool saw_asm_flag = false; start_sequence (); + + if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32) + map_egpr_constraints (constraints); + for (unsigned i = 0, n = outputs.length (); i < n; ++i) { const char *con = constraints[i]; diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index d89b5bb..d4a7b7e 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1335,3 +1335,8 @@ Enum(apx_features) String(ndd) Value(apx_ndd) Set(4) EnumValue Enum(apx_features) String(all) Value(apx_all) Set(1) + +mapx-inline-asm-use-gpr32 +Target Var(ix86_apx_inline_asm_use_gpr32) Init(0) +Enable GPR32 in inline asm when APX_EGPR enabled, do not +hook reg or mem constraint in inline asm to GPR16. diff --git a/gcc/testsuite/gcc.target/i386/apx-inline-gpr-norex2.c b/gcc/testsuite/gcc.target/i386/apx-inline-gpr-norex2.c new file mode 100644 index 0000000..ffd8f95 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-inline-gpr-norex2.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mapxf -m64" } */ + +typedef unsigned int u32; +typedef unsigned long long u64; + +void constraint_test () +{ + register u64 *r16 __asm__("%r16"); + register u64 r17 __asm__("%r17"); + u64 *addr = r16; + + __asm__ __volatile__ ("test_mapping_g_m %0, %%rax" : : "g" (r16) : "rax"); + __asm__ __volatile__ ("test_mapping_g_r %0, %%rax" : : "g" (r17) : "rax"); + __asm__ __volatile__ ("test_mapping_m %0, %%rax" : : "m" (addr) : "rax"); + __asm__ __volatile__ ("test_mapping_r %0, %%rax" : : "r" (r17) : "rax"); + __asm__ __volatile__ ("test_mapping_rm %0, %%rax" : "=r,m" (r16) : : "rax"); +} + +/* { dg-final { scan-assembler-not "test_mapping_g_m %r16, %rax" } } */ +/* { dg-final { scan-assembler-not "test_mapping_g_r %r17, %rax" } } */ +/* { dg-final { scan-assembler-not "test_mapping_m %r16, %rax" } } */ +/* { dg-final { scan-assembler-not "test_mapping_r %r17, %rax" } } */ +/* { dg-final { scan-assembler-not "test_mapping_rm %r16, %rax" } } */ + |