From: Kong Lingling <lingling.k...@intel.com> 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.w...@intel.com> Co-authored-by: Hongtao Liu <hongtao....@intel.com> --- gcc/config/i386/i386.cc | 92 +++++++++++++++++++ gcc/config/i386/i386.opt | 5 + .../gcc.target/i386/apx-inline-gpr-norex2.c | 25 +++++ 3 files changed, 122 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/apx-inline-gpr-norex2.c diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 5af0de4dae7..ea94663eb68 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" @@ -23161,6 +23162,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 (con, "=@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 @@ -23175,6 +23263,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 d89b5bbc5e8..d4a7b7ec839 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 00000000000..ffd8f954500 --- /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" } } */ + -- 2.31.1