1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
From 92308185917678406afee3c165ea5e71b53b3cc1 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sat, 6 Jan 2018 22:29:56 -0800
Subject: [PATCH 07/13] 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 <hongjiu.lu@intel.com>
* 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 <hongjiu.lu@intel.com>
* gcc.target/i386/indirect-thunk-register-4.c: New test.
---
gcc/config/i386/i386.c | 13 ++++++++++++-
gcc/doc/extend.texi | 3 +++
gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 +++++++++++++
3 files changed, 28 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 34e26a3a3c7..eeca7e5e490 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16869,6 +16869,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
@@ -16879,7 +16880,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)
@@ -16922,6 +16923,14 @@ print_reg (rtx x, int code, FILE *file)
&& regno != FPSR_REG
&& regno != FPCR_REG);
+ 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)
@@ -17035,6 +17044,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.
@@ -17259,6 +17269,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 2cb6bd1ef3e..76ba1d4f913 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8511,6 +8511,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 } } } } */
--
2.16.3
|