arm_hard_float #35

Merged
ariadne merged 3 commits from rlcamp/libucontext:arm_hard_float into master 2022-03-23 20:15:33 +00:00
7 changed files with 75 additions and 1 deletions

View File

@ -35,6 +35,18 @@ ifeq ($(FREESTANDING),yes)
EXPORT_UNPREFIXED = no EXPORT_UNPREFIXED = no
endif endif
FORCE_SOFT_FLOAT := no
ifeq ($(FORCE_SOFT_FLOAT),yes)
CPPFLAGS += -DFORCE_SOFT_FLOAT
endif
FORCE_HARD_FLOAT := no
ifeq ($(FORCE_HARD_FLOAT),yes)
CPPFLAGS += -DFORCE_HARD_FLOAT
endif
ifeq ($(EXPORT_UNPREFIXED),yes) ifeq ($(EXPORT_UNPREFIXED),yes)
CPPFLAGS += -DEXPORT_UNPREFIXED CPPFLAGS += -DEXPORT_UNPREFIXED
endif endif

View File

@ -101,4 +101,5 @@ ucontext functions:
save/restore FPU registers or vector registers may be added in a later release as a build-time save/restore FPU registers or vector registers may be added in a later release as a build-time
setting -- for now, we assume a soft-float ABI with no optional processor features. In practice, this setting -- for now, we assume a soft-float ABI with no optional processor features. In practice, this
does not really matter, code using these functions are unlikely to be impacted by this design does not really matter, code using these functions are unlikely to be impacted by this design
assumption. assumption. This is a work in progress, as newer compilers will spill even non-floating-point state
through floating point registers when allowed to do so.

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}