diff mbox series

[5/5] x86: Add 'V' register operand modifier

Message ID 20180107225904.11535-6-hjl.tools@gmail.com
State New
Headers show
Series x86: CVE-2017-5715, aka Spectre | expand

Commit Message

H.J. Lu Jan. 7, 2018, 10:59 p.m. UTC
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.
---
 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

Comments

Jeff Law Jan. 11, 2018, 11:11 p.m. UTC | #1
On 01/07/2018 03:59 PM, H.J. Lu wrote:
> 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.
No comments from me.  Uros has final call here.

jeff
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b75fc48a4da..2627e57a47e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -17591,6 +17591,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
@@ -17601,7 +17602,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)
@@ -17653,6 +17654,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)
@@ -17772,6 +17781,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.
@@ -17995,6 +18005,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 7690a2bdb7d..97a420155a4 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -9273,6 +9273,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 } } } } */