]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.asm
MdePkg/Library/BaseLib: Enable VS2017/ARM64 builds
[mirror_edk2.git] / MdePkg / Library / BaseLib / AArch64 / SetJumpLongJump.asm
CommitLineData
da351bdb
PB
1;------------------------------------------------------------------------------\r
2;\r
3; Copyright (c) 2009-2013, ARM Ltd. All rights reserved.\r
4; This program and the accompanying materials\r
5; are licensed and made available under the terms and conditions of the BSD License\r
6; which accompanies this distribution. The full text of the license may be found at\r
7; http://opensource.org/licenses/bsd-license.php.\r
8;\r
9; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11;\r
12;------------------------------------------------------------------------------\r
13\r
14 EXPORT SetJump\r
15 EXPORT InternalLongJump\r
16 AREA BaseLib_LowLevel, CODE, READONLY\r
17\r
18#define GPR_LAYOUT \\r
19 REG_PAIR (x19, x20, #0); \\r
20 REG_PAIR (x21, x22, #16); \\r
21 REG_PAIR (x23, x24, #32); \\r
22 REG_PAIR (x25, x26, #48); \\r
23 REG_PAIR (x27, x28, #64); \\r
24 REG_PAIR (x29, x30, #80);/*FP, LR*/ \\r
25 REG_ONE (x16, #96) /*IP0*/\r
26\r
27#define FPR_LAYOUT \\r
28 REG_PAIR ( d8, d9, #112); \\r
29 REG_PAIR (d10, d11, #128); \\r
30 REG_PAIR (d12, d13, #144); \\r
31 REG_PAIR (d14, d15, #160);\r
32\r
33;/**\r
34; Saves the current CPU context that can be restored with a call to LongJump() and returns 0.#\r
35;\r
36; Saves the current CPU context in the buffer specified by JumpBuffer and returns 0. The initial\r
37; call to SetJump() must always return 0. Subsequent calls to LongJump() cause a non-zero\r
38; value to be returned by SetJump().\r
39;\r
40; If JumpBuffer is NULL, then ASSERT().\r
41; For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().\r
42;\r
43; @param JumpBuffer A pointer to CPU context buffer.\r
44;\r
45;**/\r
46;\r
47;UINTN\r
48;EFIAPI\r
49;SetJump (\r
50; IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer // X0\r
51; );\r
52;\r
53SetJump\r
54 mov x16, sp // use IP0 so save SP\r
55#define REG_PAIR(REG1, REG2, OFFS) stp REG1, REG2, [x0, OFFS]\r
56#define REG_ONE(REG1, OFFS) str REG1, [x0, OFFS]\r
57 GPR_LAYOUT\r
58 FPR_LAYOUT\r
59#undef REG_PAIR\r
60#undef REG_ONE\r
61 mov w0, #0\r
62 ret\r
63\r
64;/**\r
65; Restores the CPU context that was saved with SetJump().#\r
66;\r
67; Restores the CPU context from the buffer specified by JumpBuffer.\r
68; This function never returns to the caller.\r
69; Instead is resumes execution based on the state of JumpBuffer.\r
70;\r
71; @param JumpBuffer A pointer to CPU context buffer.\r
72; @param Value The value to return when the SetJump() context is restored.\r
73;\r
74;**/\r
75;VOID\r
76;EFIAPI\r
77;InternalLongJump (\r
78; IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, // X0\r
79; IN UINTN Value // X1\r
80; );\r
81;\r
82InternalLongJump\r
83#define REG_PAIR(REG1, REG2, OFFS) ldp REG1, REG2, [x0, OFFS]\r
84#define REG_ONE(REG1, OFFS) ldr REG1, [x0, OFFS]\r
85 GPR_LAYOUT\r
86 FPR_LAYOUT\r
87#undef REG_PAIR\r
88#undef REG_ONE\r
89 mov sp, x16\r
90 cmp w1, #0\r
91 mov w0, #1\r
92 beq exit\r
93 mov w0, w1\r
94exit\r
95 // use br not ret, as ret is guaranteed to mispredict\r
96 br x30\r
97\r
98ASM_FUNCTION_REMOVE_IF_UNREFERENCED\r
99\r
100 END\r
101\r