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