x86: add architecture enabled ps_shr()

This shows how we can add an architecture enabled optimization for
ps_shr(). This is currently disabled though as I'm sure the asm is
not right yet. Once the x86 asm is fixed in the header file
arch/x86/include/asm/ps_const.h just edit the top level Makefile and
uncomment:

  #CFLAGS += -DCONFIG_HAVE_ARCH_PS_CONST

Expected synth driver output:

Synthetics: ps_shr(0xDEADBEEF, get_demo_shr) returns: 0x0000DEAD

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
diff --git a/Makefile b/Makefile
index 08115d6..aa8e382 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,7 @@
 CFLAGS += -std=gnu99 -Wall -Werror
 CFLAGS += -pthread
 CFLAGS += -DCONFIG_KPROBES
+#CFLAGS += -DCONFIG_HAVE_ARCH_PS_CONST
 INCLUDES = -I include/ -I arch/x86/include/
 CFLAGS += $(INCLUDES)
 
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
new file mode 100644
index 0000000..155a529
--- /dev/null
+++ b/arch/x86/include/asm/asm.h
@@ -0,0 +1,17 @@
+#ifndef _ASM_X86_ASM_H
+
+#ifdef __ASSEMBLY__
+# define __ASM_FORM(x)	x
+# define __ASM_FORM_RAW(x)     x
+# define __ASM_FORM_COMMA(x) x,
+#else
+# define __ASM_FORM(x)	" " #x " "
+# define __ASM_FORM_RAW(x)     #x
+# define __ASM_FORM_COMMA(x) " " #x ","
+#endif
+
+# define __ASM_SEL(a,b) __ASM_FORM(b)
+# define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b)
+#define _ASM_PTR	__ASM_SEL(.long, .quad)
+
+#endif /* _ASM_X86_ASM_H */
diff --git a/arch/x86/include/asm/ps_const.h b/arch/x86/include/asm/ps_const.h
new file mode 100644
index 0000000..b9901f3
--- /dev/null
+++ b/arch/x86/include/asm/ps_const.h
@@ -0,0 +1,21 @@
+#ifndef __X86_PS_CONST
+#define __X86_PS_CONST
+
+#include <linux/tables.h>
+#include <asm/asm.h>
+
+#define ps_shr(_in, _func)						\
+({									\
+	__typeof__(_in) _out;						\
+	asm volatile(							\
+		"shr $0,%0\n"						\
+		"1:\n"							\
+		SECTION_TBL_STR(SECTION_INIT_DATA, ps_set_const_table, 01)\
+		_ASM_PTR "1b-1, %P2, %P3\n"				\
+		".popsection\n"						\
+		: "=rm" (_out)						\
+		: "0" (_in), "i" (SET_CONST_U8), "i" (_func));		\
+	(_out);								\
+})
+
+#endif /* __X86_PS_CONST */
diff --git a/include/linux/ps_const.h b/include/linux/ps_const.h
index 1747421..5eab3a1 100644
--- a/include/linux/ps_const.h
+++ b/include/linux/ps_const.h
@@ -21,6 +21,10 @@
 
 DECLARE_LINKTABLE(struct ps_set_const, ps_set_const_table);
 
+#ifdef CONFIG_HAVE_ARCH_PS_CONST
+#include <asm/ps_const.h>
+#endif
+
 /*
  * ps_ stands for "partially static", so we "partialloy static shift right"
  * You can optimize this for your architecture.