summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-11-29 16:10:36 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-11-29 16:10:41 +0100
commit5dbc6990b16a969e470392abe48e8ff9552780b3 (patch)
tree1083b9189aace9dc2fd06e011df515e72d79f4af
parent231bd7fdc04517389135a4958294cf7630617385 (diff)
x86: Factorize fpu save/restore
* i386/i386/fpu.h (fpu_save, fpu_rstor): New macros. (fpu_save_context): Use fpu_save macro. * i386/i386/fpu.c (fp_save): Use fpu_save macro. (fp_load): Use fpu_rstor macro.
-rw-r--r--i386/i386/fpu.c42
-rw-r--r--i386/i386/fpu.h67
2 files changed, 49 insertions, 60 deletions
diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c
index b177dad2..03f43f9d 100644
--- a/i386/i386/fpu.c
+++ b/i386/i386/fpu.c
@@ -825,30 +825,9 @@ fp_save(thread_t thread)
pcb_t pcb = thread->pcb;
struct i386_fpsave_state *ifps = pcb->ims.ifps;
- if (ifps != 0 && !ifps->fp_valid) {
+ if (ifps != 0 && !ifps->fp_valid)
/* registers are in FPU */
- ifps->fp_valid = TRUE;
- switch (fp_save_kind) {
- case FP_XSAVE:
- xsave(&ifps->xfp_save_state);
- break;
- case FP_XSAVEOPT:
- xsaveopt(&ifps->xfp_save_state);
- break;
- case FP_XSAVEC:
- xsavec(&ifps->xfp_save_state);
- break;
- case FP_XSAVES:
- xsaves(&ifps->xfp_save_state);
- break;
- case FP_FXSAVE:
- fxsave(&ifps->xfp_save_state);
- break;
- case FP_FNSAVE:
- fnsave(&ifps->fp_save_state);
- break;
- }
- }
+ fpu_save(ifps);
}
/*
@@ -896,22 +875,7 @@ ASSERT_IPL(SPL0);
printf("fp_load: invalid FPU state!\n");
fninit ();
} else {
- switch (fp_save_kind) {
- case FP_XSAVE:
- case FP_XSAVEOPT:
- case FP_XSAVEC:
- xrstor(ifps->xfp_save_state);
- break;
- case FP_XSAVES:
- xrstors(ifps->xfp_save_state);
- break;
- case FP_FXSAVE:
- fxrstor(ifps->xfp_save_state);
- break;
- case FP_FNSAVE:
- frstor(ifps->fp_save_state);
- break;
- }
+ fpu_rstor(ifps);
}
ifps->fp_valid = FALSE; /* in FPU */
}
diff --git a/i386/i386/fpu.h b/i386/i386/fpu.h
index c77cc96d..33838cc0 100644
--- a/i386/i386/fpu.h
+++ b/i386/i386/fpu.h
@@ -142,6 +142,51 @@ static inline void set_xcr0(uint64_t value) {
#define fpu_load_context(pcb)
+#define fpu_save(ifps) \
+ do { \
+ switch (fp_save_kind) { \
+ case FP_XSAVE: \
+ xsave(&(ifps)->xfp_save_state); \
+ break; \
+ case FP_XSAVEOPT: \
+ xsaveopt(&(ifps)->xfp_save_state); \
+ break; \
+ case FP_XSAVEC: \
+ xsavec(&(ifps)->xfp_save_state); \
+ break; \
+ case FP_XSAVES: \
+ xsaves(&(ifps)->xfp_save_state); \
+ break; \
+ case FP_FXSAVE: \
+ fxsave(&(ifps)->xfp_save_state); \
+ break; \
+ case FP_FNSAVE: \
+ fnsave(&(ifps)->fp_save_state); \
+ break; \
+ } \
+ (ifps)->fp_valid = TRUE; \
+ } while (0)
+
+#define fpu_rstor(ifps) \
+ do { \
+ switch (fp_save_kind) { \
+ case FP_XSAVE: \
+ case FP_XSAVEOPT: \
+ case FP_XSAVEC: \
+ xrstor((ifps)->xfp_save_state); \
+ break; \
+ case FP_XSAVES: \
+ xrstors((ifps)->xfp_save_state); \
+ break; \
+ case FP_FXSAVE: \
+ fxrstor((ifps)->xfp_save_state); \
+ break; \
+ case FP_FNSAVE: \
+ frstor((ifps)->fp_save_state); \
+ break; \
+ } \
+ } while (0)
+
/*
* Save thread`s FPU context.
* If only one CPU, we just set the task-switched bit,
@@ -155,27 +200,7 @@ static inline void set_xcr0(uint64_t value) {
ifps = (thread)->pcb->ims.ifps; \
if (ifps != 0 && !ifps->fp_valid) { \
/* registers are in FPU - save to memory */ \
- ifps->fp_valid = TRUE; \
- switch (fp_save_kind) { \
- case FP_XSAVE: \
- xsave(&ifps->xfp_save_state); \
- break; \
- case FP_XSAVEOPT: \
- xsaveopt(&ifps->xfp_save_state); \
- break; \
- case FP_XSAVEC: \
- xsavec(&ifps->xfp_save_state); \
- break; \
- case FP_XSAVES: \
- xsaves(&ifps->xfp_save_state); \
- break; \
- case FP_FXSAVE: \
- fxsave(&ifps->xfp_save_state); \
- break; \
- case FP_FNSAVE: \
- fnsave(&ifps->fp_save_state); \
- break; \
- } \
+ fpu_save(ifps); \
set_ts(); \
} \
}