1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * thunks.S - assembly helpers for mixed-bitness code
4 * Copyright (c) 2015 Andrew Lutomirski
5 *
6 * These are little helpers that make it easier to switch bitness on
7 * the fly.
8 */
9
10 .text
11
12 .global call32_from_64
13 .type call32_from_64, @function
14call32_from_64:
15 // rdi: stack to use
16 // esi: function to call
17
18 // Save registers
19 pushq %rbx
20 pushq %rbp
21 pushq %r12
22 pushq %r13
23 pushq %r14
24 pushq %r15
25 pushfq
26
27 // Switch stacks
28 mov %rsp,(%rdi)
29 mov %rdi,%rsp
30
31 // Switch to compatibility mode
32 pushq $0x23 /* USER32_CS */
33 pushq $1f
34 lretq
35
361:
37 .code32
38 // Call the function
39 call *%esi
40 // Switch back to long mode
41 jmp $0x33,$1f
42 .code64
43
441:
45 // Restore the stack
46 mov (%rsp),%rsp
47
48 // Restore registers
49 popfq
50 popq %r15
51 popq %r14
52 popq %r13
53 popq %r12
54 popq %rbp
55 popq %rbx
56
57 ret
58
59.size call32_from_64, .-call32_from_64
60
61.section .note.GNU-stack,"",%progbits
62

source code of linux/tools/testing/selftests/x86/thunks.S