From 8a47615dd04a02fdae9691f5ad73fd5a5530c156 Mon Sep 17 00:00:00 2001 From: hjl Date: Tue, 16 Jan 2018 11:19:51 +0000 Subject: [PATCH 8/9] x86: Add 'V' register operand modifier Add 'V', a special modifier which prints the name of the full integer register without '%'. For extern void (*func_p) (void); void foo (void) { asm ("call __x86_indirect_thunk_%V0" : : "a" (func_p)); } it generates: foo: movq func_p(%rip), %rax call __x86_indirect_thunk_rax ret gcc/ Backport from mainline 2018-01-14 H.J. Lu * config/i386/i386.c (print_reg): Print the name of the full integer register without '%'. (ix86_print_operand): Handle 'V'. * doc/extend.texi: Document 'V' modifier. gcc/testsuite/ Backport from mainline 2018-01-14 H.J. Lu * gcc.target/i386/indirect-thunk-register-4.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256736 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/i386/i386.c | 13 ++++++++++++- gcc/doc/extend.texi | 3 +++ gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 +++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 8fb8902..1bbdd0c 100644 --- a/src/gcc/config/i386/i386.c +++ b/src/gcc/config/i386/i386.c @@ -17941,6 +17941,7 @@ put_condition_code (enum rtx_code code, machine_mode mode, bool reverse, If CODE is 'h', pretend the reg is the 'high' byte register. If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. If CODE is 'd', duplicate the operand for AVX instruction. + If CODE is 'V', print naked full integer register name without %. */ void @@ -17951,7 +17952,7 @@ print_reg (rtx x, int code, FILE *file) unsigned int regno; bool duplicated = code == 'd' && TARGET_AVX; - if (ASSEMBLER_DIALECT == ASM_ATT) + if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V') putc ('%', file); if (x == pc_rtx) @@ -17999,6 +18000,14 @@ print_reg (rtx x, int code, FILE *file) else code = GET_MODE_SIZE (GET_MODE (x)); + if (code == 'V') + { + if (GENERAL_REGNO_P (regno)) + code = GET_MODE_SIZE (word_mode); + else + error ("'V' modifier on non-integer register"); + } + /* Irritatingly, AMD extended registers use different naming convention from the normal registers: "r%d[bwd]" */ if (REX_INT_REGNO_P (regno)) @@ -18118,6 +18127,7 @@ print_reg (rtx x, int code, FILE *file) & -- print some in-use local-dynamic symbol name. H -- print a memory address offset by 8; used for sse high-parts Y -- print condition for XOP pcom* instruction. + V -- print naked full integer register name without %. + -- print a branch hint as 'cs' or 'ds' prefix ; -- print a semicolon (after prefixes due to bug in older gas). ~ -- print "i" if TARGET_AVX2, "f" otherwise. @@ -18342,6 +18352,7 @@ ix86_print_operand (FILE *file, rtx x, int code) case 'X': case 'P': case 'p': + case 'V': break; case 's': diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c new file mode 100644 index 0000000..f0cd9b7 --- /dev/null +++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=keep -fno-pic" } */ + +extern void (*func_p) (void); + +void +foo (void) +{ + asm("call __x86_indirect_thunk_%V0" : : "a" (func_p)); +} + +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { target ia32 } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { target { ! ia32 } } } } */ -- 2.7.4