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