timing_test: Add cpuid and iret_to_self modes

Signed-off-by: Andy Lutomirski <luto@kernel.org>
diff --git a/timing_test.cc b/timing_test.cc
index ff8062e..1ad1b43 100644
--- a/timing_test.cc
+++ b/timing_test.cc
@@ -52,6 +52,40 @@
 	return NULL;
 }
 
+static void iret_to_self(void)
+{
+#ifndef __x86_64__
+	register void *__sp asm("esp");
+
+	asm volatile (
+		"pushl %%ss\n\t"
+		"pushl %%esp\n\t"
+		"addl $4, (%%esp)\n\t"
+		"pushfl\n\t"
+		"pushl %%cs\n\t"
+		"pushl $1f\n\t"
+		"iret\n\t"
+		"1:"
+		: "+r" (__sp) : : "cc");
+#else
+	register void *__sp asm("rsp");
+	unsigned long tmp;
+
+	asm volatile (
+		"movq %%ss, %0\n\t"
+		"pushq %0\n\t"
+		"pushq %%rsp\n\t"
+		"addq $8, (%%rsp)\n\t"
+		"pushfq\n\t"
+		"movq %%cs, %0\n\t"
+		"pushq %0\n\t"
+		"pushq $1f\n\t"
+		"iretq\n\t"
+		"1:"
+		: "=r" (tmp), "+r" (__sp) : : "cc");
+#endif
+}
+
 int main(int argc, char **argv)
 {
 	if (argc < 3) {
@@ -303,6 +337,14 @@
 				err(1, "pthread_create");
 			pthread_join(thread, NULL);
 		}
+	} else if (!strcmp(mode, "iret_to_self")) {
+		for (size_t i = 0; i < loops; ++i)
+			iret_to_self();
+	} else if (!strcmp(mode, "cpuid")) {
+		for (size_t i = 0; i < loops; ++i) {
+			unsigned int ax = 1, cx = 0;
+			asm volatile ("cpuid" : "+a" (ax), "+c" (cx) : : "ebx", "edx");
+		}
 	} else {
 		printf("Unknown mode %s\n", mode);
 		return 1;