summaryrefslogtreecommitdiff
path: root/tests/test-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-i386.c')
-rw-r--r--tests/test-i386.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/tests/test-i386.c b/tests/test-i386.c
index 5e6e6c624c..310a93aebe 100644
--- a/tests/test-i386.c
+++ b/tests/test-i386.c
@@ -1321,8 +1321,25 @@ void test_code16(void)
}
#endif
-extern char func_lret32;
-extern char func_iret32;
+#if defined(__x86_64__)
+asm(".globl func_lret\n"
+ "func_lret:\n"
+ "movl $0x87654641, %eax\n"
+ "lretq\n");
+#else
+asm(".globl func_lret\n"
+ "func_lret:\n"
+ "movl $0x87654321, %eax\n"
+ "lret\n"
+
+ ".globl func_iret\n"
+ "func_iret:\n"
+ "movl $0xabcd4321, %eax\n"
+ "iret\n");
+#endif
+
+extern char func_lret;
+extern char func_iret;
void test_misc(void)
{
@@ -1334,16 +1351,53 @@ void test_misc(void)
asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
printf("xlat: EAX=" FMTLX "\n", res);
-#if !defined(__x86_64__)
+#if defined(__x86_64__)
+ {
+ static struct __attribute__((packed)) {
+ uint32_t offset;
+ uint16_t seg;
+ } desc;
+ long cs_sel;
+
+ asm volatile ("mov %%cs, %0" : "=r" (cs_sel));
+
+ asm volatile ("push %1\n"
+ "call func_lret\n"
+ : "=a" (res)
+ : "r" (cs_sel) : "memory", "cc");
+ printf("func_lret=" FMTLX "\n", res);
+
+ /* NOTE: we assume that &func_lret < 4GB */
+ desc.offset = (long)&func_lret;
+ desc.seg = cs_sel;
+
+ asm volatile ("xor %%rax, %%rax\n"
+ "rex64 lcall %1\n"
+ : "=a" (res)
+ : "m" (desc)
+ : "memory", "cc");
+ printf("func_lret2=" FMTLX "\n", res);
+
+ asm volatile ("push %2\n"
+ "mov $ 1f, %%rax\n"
+ "push %%rax\n"
+ "ljmp %1\n"
+ "1:\n"
+ : "=a" (res)
+ : "m" (desc), "b" (cs_sel)
+ : "memory", "cc");
+ printf("func_lret3=" FMTLX "\n", res);
+ }
+#else
asm volatile ("push %%cs ; call %1"
: "=a" (res)
- : "m" (func_lret32): "memory", "cc");
- printf("func_lret32=" FMTLX "\n", res);
+ : "m" (func_lret): "memory", "cc");
+ printf("func_lret=" FMTLX "\n", res);
asm volatile ("pushf ; push %%cs ; call %1"
: "=a" (res)
- : "m" (func_iret32): "memory", "cc");
- printf("func_iret32=" FMTLX "\n", res);
+ : "m" (func_iret): "memory", "cc");
+ printf("func_iret=" FMTLX "\n", res);
#endif
#if defined(__x86_64__)