Added arm conditional vfp save/restore

arm_hard_float
Richard Campbell 2022-03-04 10:35:25 -08:00
parent 4dde3417b4
commit 7bc3e90984
5 changed files with 61 additions and 0 deletions

View File

@ -2,6 +2,8 @@
#define REG_SZ (4) #define REG_SZ (4)
#define MCONTEXT_GREGS (32) #define MCONTEXT_GREGS (32)
#define VFP_MAGIC_OFFSET (232)
#define VFP_D8_OFFSET (304)
#define TYPE(__proc) #define TYPE(__proc)

View File

@ -22,6 +22,27 @@ FUNC(libucontext_getcontext)
str r13, [r0, #REG_OFFSET(13)] str r13, [r0, #REG_OFFSET(13)]
str r14, [r0, #REG_OFFSET(15)] str r14, [r0, #REG_OFFSET(15)]
#ifndef FORCE_SOFT_FLOAT
#ifndef FORCE_HARD_FLOAT
/* test for vfp, set kernel-defined magic number in uc_regspace */
push {r0-r1,fp,lr}
mov r0, #16
bl getauxval
tst r0, #64
pop {r0-r1,fp,lr}
moveq r2, #0
ldrne r2, =#0x56465001
str r2, [r0, #VFP_MAGIC_OFFSET]
beq 1f
#endif
/* if vfp detected, save d8-d15 */
.fpu vfp
add r1, r0, #VFP_D8_OFFSET
vstmia r1, {d8-d15}
.fpu softvfp
1:
#endif
/* return 0 */ /* return 0 */
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr

View File

@ -23,6 +23,8 @@ typedef struct libucontext_ucontext {
struct libucontext_ucontext *uc_link; struct libucontext_ucontext *uc_link;
libucontext_stack_t uc_stack; libucontext_stack_t uc_stack;
libucontext_mcontext_t uc_mcontext; libucontext_mcontext_t uc_mcontext;
unsigned long uc_sigmask[128 / sizeof(long)];
unsigned long long uc_regspace[64];
} libucontext_ucontext_t; } libucontext_ucontext_t;
#endif #endif

View File

@ -16,6 +16,22 @@ ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext) ALIAS(__setcontext, libucontext_setcontext)
FUNC(libucontext_setcontext) FUNC(libucontext_setcontext)
#ifndef FORCE_SOFT_FLOAT
#ifndef FORCE_HARD_FLOAT
/* test for vfp magic number set by getcontext */
ldr r2, [r0, #VFP_MAGIC_OFFSET]
ldr r3, =#0x56465001
cmp r2, r3
bne 1f
#endif
/* if vfp in use, restore d8-d15 from uc_regspace */
.fpu vfp
add r14, r0, #VFP_D8_OFFSET
vldmia r14, {d8-d15}
.fpu softvfp
1:
#endif
/* copy all of the current registers into the ucontext structure */ /* copy all of the current registers into the ucontext structure */
add r14, r0, #REG_OFFSET(0) add r14, r0, #REG_OFFSET(0)
ldmia r14, {r0-r12} ldmia r14, {r0-r12}

View File

@ -22,6 +22,26 @@ FUNC(libucontext_swapcontext)
str r13, [r0,#REG_OFFSET(13)] str r13, [r0,#REG_OFFSET(13)]
str r14, [r0,#REG_OFFSET(15)] str r14, [r0,#REG_OFFSET(15)]
#ifndef FORCE_SOFT_FLOAT
#ifndef FORCE_HARD_FLOAT
/* test for vfp magic number, copy to other ucontext */
ldr r3, [r1, #VFP_MAGIC_OFFSET]
ldr r4, =#0x56465001
str r3, [r0, #VFP_MAGIC_OFFSET]
cmp r3, r4
bne 1f
#endif
/* if vfp in use, save and restore d8-d15 */
.fpu vfp
add r2, r0, #VFP_D8_OFFSET
vstmia r2, {d8-d15}
add r14, r1, #VFP_D8_OFFSET
vldmia r14, {d8-d15}
.fpu softvfp
1:
#endif
/* load new registers from the second ucontext structure */ /* load new registers from the second ucontext structure */
add r14, r1, #REG_OFFSET(0) add r14, r1, #REG_OFFSET(0)
ldmia r14, {r0-r12} ldmia r14, {r0-r12}