summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-01-06 22:29:56 -0800
committerH.J. Lu <hjl.tools@gmail.com>2018-01-07 09:33:49 -0800
commit239f35ff64ab458871628e5aafcdc2a866316783 (patch)
treea496a5992cdd1cc5c6854a77e204e7fa730eeeb6
parent657defef2faf9dc82e4f7ea8579c8ed944bfbce8 (diff)
downloadgcc-hjl/indirect/gcc-7-branch/loop.tar.gz
x86: Add 'V' register operand modifierhjl/indirect/gcc-7-branch/loop
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/ * 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/ * gcc.target/i386/indirect-thunk-register-4.c: New test.
-rw-r--r--gcc/config/i386/i386.c13
-rw-r--r--gcc/doc/extend.texi3
-rw-r--r--gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c13
3 files changed, 28 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b4c02be5020..1d38423c9ba 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -17897,6 +17897,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
@@ -17907,7 +17908,7 @@ print_reg (rtx x, int code, FILE *file)
unsigned int regno;
bool duplicated;
- if (ASSEMBLER_DIALECT == ASM_ATT)
+ if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
putc ('%', file);
if (x == pc_rtx)
@@ -17955,6 +17956,14 @@ print_reg (rtx x, int code, FILE *file)
return;
}
+ if (code == 'V')
+ {
+ if (GENERAL_REGNO_P (regno))
+ msize = GET_MODE_SIZE (word_mode);
+ else
+ error ("'V' modifier on non-integer register");
+ }
+
duplicated = code == 'd' && TARGET_AVX;
switch (msize)
@@ -18074,6 +18083,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.
@@ -18298,6 +18308,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/doc/extend.texi b/gcc/doc/extend.texi
index 46e0a3623a6..9db9e0e27e9 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8778,6 +8778,9 @@ The table below shows the list of supported modifiers and their effects.
@tab @code{2}
@end multitable
+@code{V} is a special modifier which prints the name of the full integer
+register without @code{%}.
+
@anchor{x86floatingpointasmoperands}
@subsubsection x86 Floating-Point @code{asm} Operands
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 00000000000..f0cd9b75be8
--- /dev/null
+++ b/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 } } } } */